# CreateAnnotationLog Source: https://docs.siftstack.com/api-reference/annotationlogservice/createannotationlog /openapi.json post /api/v1/annotations/{annotationId}/logs Creates an annotation log on an annotation. # DeleteAnnotationLog Source: https://docs.siftstack.com/api-reference/annotationlogservice/deleteannotationlog /openapi.json delete /api/v1/annotations/{annotationId}/logs/{annotationLogId} Deletes an annotation log. # ListAnnotationLogs Source: https://docs.siftstack.com/api-reference/annotationlogservice/listannotationlogs /openapi.json get /api/v1/annotation-logs Retrieves annotation logs using an optional filter. # ListAnnotationLogs Source: https://docs.siftstack.com/api-reference/annotationlogservice/listannotationlogs-1 /openapi.json get /api/v1/annotations/{annotationId}/logs Retrieves annotation logs using an optional filter. # ArchiveAnnotation Source: https://docs.siftstack.com/api-reference/annotationservice/archiveannotation /openapi.json post /api/v1/annotations/{annotationId}:archive Archives an annotation. # BatchArchiveAnnotations Source: https://docs.siftstack.com/api-reference/annotationservice/batcharchiveannotations /openapi.json post /api/v1/annotations:batchArchive Batch archives annotations. # BatchDeleteAnnotation Source: https://docs.siftstack.com/api-reference/annotationservice/batchdeleteannotation /openapi.json post /api/v1/annotations:batchDelete Batch archives annotations. # BatchUnarchiveAnnotations Source: https://docs.siftstack.com/api-reference/annotationservice/batchunarchiveannotations /openapi.json post /api/v1/annotations:batchUnarchive Batch unarchives annotations. # CreateAnnotation Source: https://docs.siftstack.com/api-reference/annotationservice/createannotation /openapi.json post /api/v1/annotations Creates an annotation. # DeleteAnnotation Source: https://docs.siftstack.com/api-reference/annotationservice/deleteannotation /openapi.json delete /api/v1/annotations/{annotationId} Archives an annotation. # GetAnnotation Source: https://docs.siftstack.com/api-reference/annotationservice/getannotation /openapi.json get /api/v1/annotations/{annotationId} Retrieves an annotation # ListAnnotation Source: https://docs.siftstack.com/api-reference/annotationservice/listannotation /openapi.json get /api/v1/annotations Retrieves annotations using an optional filter. # UnarchiveAnnotation Source: https://docs.siftstack.com/api-reference/annotationservice/unarchiveannotation /openapi.json post /api/v1/annotations/{annotationId}:unarchive Unarchives an annotation. # UpdateAnnotation Source: https://docs.siftstack.com/api-reference/annotationservice/updateannotation /openapi.json patch /api/v1/annotations Updates an existing annotation using using the list of fields specified in `update_mask`. # ApiKeyOrganization Source: https://docs.siftstack.com/api-reference/apikeyservice/apikeyorganization /openapi.json get /api/v2/api-keys/organization Retrieves the organization for an API key. # CreateApiKey Source: https://docs.siftstack.com/api-reference/apikeyservice/createapikey /openapi.json post /api/v2/api-keys Creates an API key. # DeleteApiKey Source: https://docs.siftstack.com/api-reference/apikeyservice/deleteapikey /openapi.json delete /api/v2/api-keys/{apiKeyId} Deletes an API key. # ListApiKeys Source: https://docs.siftstack.com/api-reference/apikeyservice/listapikeys /openapi.json get /api/v2/api-keys Retrieves API keys using an optional filter. # ArchiveArtifact Source: https://docs.siftstack.com/api-reference/artifactservice/archiveartifact /openapi.json post /api/v1/artifacts/{artifactId}/archive Archive an artifact. Versions, stored bytes, and conversation links are left in place. # CreateArtifact Source: https://docs.siftstack.com/api-reference/artifactservice/createartifact /openapi.json post /api/v1/artifacts Create a new artifact or append a version to an existing one. # GetArtifact Source: https://docs.siftstack.com/api-reference/artifactservice/getartifact /openapi.json get /api/v1/artifacts/{artifactId} Get one artifact, resolved to the latest version unless artifact_version_id pins one. # LinkArtifactToConversation Source: https://docs.siftstack.com/api-reference/artifactservice/linkartifacttoconversation /openapi.json post /api/v1/artifacts/{artifactId}/conversations/{conversationId}:link Link an existing artifact to a conversation. # ListArtifacts Source: https://docs.siftstack.com/api-reference/artifactservice/listartifacts /openapi.json get /api/v1/artifacts List artifacts in the caller's organization, optionally filtered to one conversation. # ListArtifactVersions Source: https://docs.siftstack.com/api-reference/artifactservice/listartifactversions /openapi.json get /api/v1/artifacts/{artifactId}/versions List the version history of one artifact, newest first. # UnarchiveArtifact Source: https://docs.siftstack.com/api-reference/artifactservice/unarchiveartifact /openapi.json post /api/v1/artifacts/{artifactId}/unarchive Unarchive an artifact. # UnlinkArtifactFromConversation Source: https://docs.siftstack.com/api-reference/artifactservice/unlinkartifactfromconversation /openapi.json post /api/v1/artifacts/{artifactId}/conversations/{conversationId}:unlink Remove a conversation's link to an artifact. # ArchiveAsset Source: https://docs.siftstack.com/api-reference/assetservice/archiveasset /openapi.json post /api/v1/assets/{assetId}/archive Archives an asset. # CreateAsset Source: https://docs.siftstack.com/api-reference/assetservice/createasset /openapi.json post /api/v1/assets Creates a new, empty asset. # DeleteAsset Source: https://docs.siftstack.com/api-reference/assetservice/deleteasset /openapi.json delete /api/v1/assets/{assetId} Deletes an asset. # GetAsset Source: https://docs.siftstack.com/api-reference/assetservice/getasset /openapi.json get /api/v1/assets/{assetId} Retrieves an asset. # ListAssets Source: https://docs.siftstack.com/api-reference/assetservice/listassets /openapi.json get /api/v1/assets Retrieves assets using an optional filter. # UpdateAsset Source: https://docs.siftstack.com/api-reference/assetservice/updateasset /openapi.json patch /api/v1/assets Update fields on an asset. # CreateAutomationTrigger Source: https://docs.siftstack.com/api-reference/automationservice/createautomationtrigger /openapi.json post /api/v1/automation-triggers Create an automation trigger. # DeleteAutomationTrigger Source: https://docs.siftstack.com/api-reference/automationservice/deleteautomationtrigger /openapi.json delete /api/v1/automation-triggers/{automationTriggerId} Soft-delete an automation trigger by setting its archived_date. # GetAutomationTrigger Source: https://docs.siftstack.com/api-reference/automationservice/getautomationtrigger /openapi.json get /api/v1/automation-triggers/{automationTriggerId} Retrieve an automation trigger by ID. # ListAutomationTriggeredEvents Source: https://docs.siftstack.com/api-reference/automationservice/listautomationtriggeredevents /openapi.json get /api/v1/automation-triggered-events Retrieve and optionally filter a list of automation triggered events. # ListAutomationTriggers Source: https://docs.siftstack.com/api-reference/automationservice/listautomationtriggers /openapi.json get /api/v1/automation-triggers Retrieve and optionally filter a list of automation triggers. # UpdateAutomationTrigger Source: https://docs.siftstack.com/api-reference/automationservice/updateautomationtrigger /openapi.json patch /api/v1/automation-triggers Update select fields of an existing automation trigger. # BatchResolveCalculatedChannel Source: https://docs.siftstack.com/api-reference/calculatedchannelservice/batchresolvecalculatedchannel /openapi.json post /api/v2/calculated-channels/resolve:batch Resolve a batch of calculated channels into expressions with references # CreateCalculatedChannel Source: https://docs.siftstack.com/api-reference/calculatedchannelservice/createcalculatedchannel /openapi.json post /api/v2/calculated-channels Create a calculated channel. # GetCalculatedChannel Source: https://docs.siftstack.com/api-reference/calculatedchannelservice/getcalculatedchannel /openapi.json get /api/v2/calculated-channels/{calculatedChannelId} Retrieve the latest version of a calculated channel. # GetCalculatedChannel Source: https://docs.siftstack.com/api-reference/calculatedchannelservice/getcalculatedchannel-1 /openapi.json get /v2/organizations/{organizationId}/calculated-channels/{clientKey} Retrieve the latest version of a calculated channel. # GetCalculatedChannelDependents Source: https://docs.siftstack.com/api-reference/calculatedchannelservice/getcalculatedchanneldependents /openapi.json get /api/v2/calculated-channels/dependents Retrieve calculated channels that depend on a given calculated channel. # GetCalculatedChannelVersions Source: https://docs.siftstack.com/api-reference/calculatedchannelservice/getcalculatedchannelversions /openapi.json get /api/v2/calculated-channels/versions Retrieve calculated channel versions by their version IDs. # ListCalculatedChannels Source: https://docs.siftstack.com/api-reference/calculatedchannelservice/listcalculatedchannels /openapi.json get /api/v2/calculated-channels Retrieve the latest versions of calculated channels based on an optional filter. # ListCalculatedChannelVersions Source: https://docs.siftstack.com/api-reference/calculatedchannelservice/listcalculatedchannelversions /openapi.json get /api/v2/calculated-channels/{calculatedChannelId}/versions List versions of a particular calculated channel with an optional filter. # ListCalculatedChannelVersions Source: https://docs.siftstack.com/api-reference/calculatedchannelservice/listcalculatedchannelversions-1 /openapi.json get /v2/organizations/{organizationId}/calculated-channels/{clientKey}/versions List versions of a particular calculated channel with an optional filter. # ListResolvedCalculatedChannels Source: https://docs.siftstack.com/api-reference/calculatedchannelservice/listresolvedcalculatedchannels /openapi.json get /api/v2/calculated-channels/resolved Retrieve the latest versions of calculated channels based on an optional filter. # ResolveCalculatedChannel Source: https://docs.siftstack.com/api-reference/calculatedchannelservice/resolvecalculatedchannel /openapi.json post /api/v2/calculated-channels/resolve Resolve a calculated channel into an expression with references # UpdateCalculatedChannel Source: https://docs.siftstack.com/api-reference/calculatedchannelservice/updatecalculatedchannel /openapi.json patch /api/v2/calculated-channels Update and create a new version of a calculated channel. # ListExpressionIdentifiers Source: https://docs.siftstack.com/api-reference/calculatedchannelsservice/listexpressionidentifiers /openapi.json get /api/v1/calculated-channels:expression-identifiers Retrieves a list of valid identifiers that can be used as part of a calculated channel expression. # ValidateExpression Source: https://docs.siftstack.com/api-reference/calculatedchannelsservice/validateexpression /openapi.json post /api/v1/calculated-channels:validate-expression Used to validate whether or not an expression used for a calculated channel is valid. # CreateCampaign Source: https://docs.siftstack.com/api-reference/campaignservice/createcampaign /openapi.json post /api/v1/campaigns Create a campaign. # GetCampaign Source: https://docs.siftstack.com/api-reference/campaignservice/getcampaign /openapi.json get /api/v1/campaigns/{campaignId} Retrieve a campaign. # GetCampaign Source: https://docs.siftstack.com/api-reference/campaignservice/getcampaign-1 /openapi.json get /v1/organizations/{organizationId}/campaigns/{clientKey} Retrieve a campaign. # GetCampaignReportSummaries Source: https://docs.siftstack.com/api-reference/campaignservice/getcampaignreportsummaries /openapi.json post /api/v1/campaigns:report-summaries Returns per-campaign report summaries in bulk. # ListCampaignAnnotations Source: https://docs.siftstack.com/api-reference/campaignservice/listcampaignannotations /openapi.json get /api/v1/campaigns/{campaignId}/annotations List annotations for a campaign. # ListCampaigns Source: https://docs.siftstack.com/api-reference/campaignservice/listcampaigns /openapi.json get /api/v1/campaigns List campaigns. # UpdateCampaign Source: https://docs.siftstack.com/api-reference/campaignservice/updatecampaign /openapi.json patch /api/v1/campaigns Updates an existing campaign using the list of fields specified in `update_mask`. # BatchCreateChannelSchemas Source: https://docs.siftstack.com/api-reference/channelschemaservice/batchcreatechannelschemas /openapi.json post /api/v1/channel-schemas:batch-create Create a batch of channel schemas # BatchCreateChannelSchemas Source: https://docs.siftstack.com/api-reference/channelschemaservice/batchcreatechannelschemas-1 /openapi.json post /api/v2/channel-schemas:batch-create Create a batch of channel schemas # CreateChannelSchema Source: https://docs.siftstack.com/api-reference/channelschemaservice/createchannelschema /openapi.json post /api/v1/channel-schemas Create a channel schema # CreateChannelSchema Source: https://docs.siftstack.com/api-reference/channelschemaservice/createchannelschema-1 /openapi.json post /api/v2/channel-schemas Create a channel schema # BatchArchiveChannels Source: https://docs.siftstack.com/api-reference/channelservice/batcharchivechannels /openapi.json post /api/v3/channels:batchArchive Batch archives channels by setting active to false. # BatchUnarchiveChannels Source: https://docs.siftstack.com/api-reference/channelservice/batchunarchivechannels /openapi.json post /api/v3/channels:batchUnarchive Batch unarchives channels by setting active to true. # GetChannel Source: https://docs.siftstack.com/api-reference/channelservice/getchannel /openapi.json get /api/v2/channels/{channelId} Retrieve a channel. # GetChannel Source: https://docs.siftstack.com/api-reference/channelservice/getchannel-1 /openapi.json get /api/v3/channels/{channelId} Retrieve a channel. # ListChannels Source: https://docs.siftstack.com/api-reference/channelservice/listchannels /openapi.json get /api/v2/channels Retrieve channels using an optional filter. # ListChannels Source: https://docs.siftstack.com/api-reference/channelservice/listchannels-1 /openapi.json get /api/v3/channels Retrieve channels using an optional filter. # UpdateChannel Source: https://docs.siftstack.com/api-reference/channelservice/updatechannel /openapi.json patch /api/v3/channels Update a channel. # CreateComment Source: https://docs.siftstack.com/api-reference/commentservice/createcomment /openapi.json post /api/v1/comments Creates a comment on a resource. # DeleteComment Source: https://docs.siftstack.com/api-reference/commentservice/deletecomment /openapi.json delete /api/v1/comments/{commentId} Deletes a comment. # ListComments Source: https://docs.siftstack.com/api-reference/commentservice/listcomments /openapi.json get /api/v1/comments Retrieves comments using an optional filter. # UpdateComment Source: https://docs.siftstack.com/api-reference/commentservice/updatecomment /openapi.json patch /api/v1/comments/{comment.commentId} Updates the body of an existing comment. # CreateDataImportFromUpload Source: https://docs.siftstack.com/api-reference/dataimportservice/createdataimportfromupload /openapi.json post /api/v2/data-imports:upload Creates a data import from a file upload. # CreateDataImportFromUrl Source: https://docs.siftstack.com/api-reference/dataimportservice/createdataimportfromurl /openapi.json post /api/v2/data-imports:url Creates a data import from a file hosted at a url. # DetectConfig Source: https://docs.siftstack.com/api-reference/dataimportservice/detectconfig /openapi.json post /api/v2/data-imports:detect-config Detects the config for a data import. # GetDataImport Source: https://docs.siftstack.com/api-reference/dataimportservice/getdataimport /openapi.json get /api/v2/data-imports/{dataImportId} Gets a data import. # ListDataImports Source: https://docs.siftstack.com/api-reference/dataimportservice/listdataimports /openapi.json get /api/v2/data-imports Lists all data imports. # RetryDataImport Source: https://docs.siftstack.com/api-reference/dataimportservice/retrydataimport /openapi.json post /api/v2/data-imports/{dataImportId}:retry Retries a data import. # GetData Source: https://docs.siftstack.com/api-reference/dataservice/getdata /openapi.json post /api/v1/data Query data # GetData Source: https://docs.siftstack.com/api-reference/dataservice/getdata-1 /openapi.json post /api/v2/data Query data # List Ingestion Dead Letter Queue Errors Source: https://docs.siftstack.com/api-reference/dlqerrorsservice/list-ingestion-dead-letter-queue-errors /openapi.json get /api/v2/dlq-errors Retrieve Ingestion errors. # ReadDoc Source: https://docs.siftstack.com/api-reference/docsservice/readdoc /openapi.json get /api/v1/docs:read Read the full markdown of a Sift documentation page by path. # SearchDocs Source: https://docs.siftstack.com/api-reference/docsservice/searchdocs /openapi.json get /api/v1/docs:search Keyword search across Sift's product documentation. # ExportData Source: https://docs.siftstack.com/api-reference/exportservice/exportdata /openapi.json post /api/v1/export Export data. # GetDownloadUrl Source: https://docs.siftstack.com/api-reference/exportservice/getdownloadurl /openapi.json get /api/v1/export/{jobId}/download-url Retrieve the download URL for a completed job. # GenerateToken Source: https://docs.siftstack.com/api-reference/externalsyncservice/generatetoken /openapi.json post /api/v1/external-sync:generate-token Generates a token for synchronizing an organization's users and groups # GetExternalSyncRun Source: https://docs.siftstack.com/api-reference/externalsyncservice/getexternalsyncrun /openapi.json get /api/v1/external-sync/runs/{externalSyncRunId} Get one external sync run including the full diff payload # GetIsOrgExternallyProvisioned Source: https://docs.siftstack.com/api-reference/externalsyncservice/getisorgexternallyprovisioned /openapi.json get /api/v1/external-sync:is-org-externally-provisioned Returns whether the organization is configured for external (SCIM) user provisioning # GetTokenDetails Source: https://docs.siftstack.com/api-reference/externalsyncservice/gettokendetails /openapi.json get /api/v1/external-sync Get details about the most recent token generated, does not include the token itself # ListExternalSyncRuns Source: https://docs.siftstack.com/api-reference/externalsyncservice/listexternalsyncruns /openapi.json get /api/v1/external-sync:list-runs List historical external sync runs for the organization (newest first by default) # ListExternalSyncTokens Source: https://docs.siftstack.com/api-reference/externalsyncservice/listexternalsynctokens /openapi.json get /api/v1/external-sync:list-tokens List all tokens created by org # SyncOrganization Source: https://docs.siftstack.com/api-reference/externalsyncservice/syncorganization /openapi.json post /api/v1/external-sync Synchronizes an organization's users and groups # CreateFamily Source: https://docs.siftstack.com/api-reference/familyservice/createfamily /openapi.json post /api/v1/families Creates a new family. # CreateFamilyStatRanges Source: https://docs.siftstack.com/api-reference/familyservice/createfamilystatranges /openapi.json post /api/v1/family_stats/create-ranges Creates family stat ranges for existing family stats (within a given family). # ExportFamily Source: https://docs.siftstack.com/api-reference/familyservice/exportfamily /openapi.json get /api/v1/families/client_key/{clientKey}/export Exports a family to YAML. # ExportFamily Source: https://docs.siftstack.com/api-reference/familyservice/exportfamily-1 /openapi.json get /api/v1/families/versions/{familyVersionId}/export Exports a family to YAML. # ExportFamily Source: https://docs.siftstack.com/api-reference/familyservice/exportfamily-2 /openapi.json get /api/v1/families/{familyId}/export Exports a family to YAML. # GenerateFamilyStatRangeName Source: https://docs.siftstack.com/api-reference/familyservice/generatefamilystatrangename /openapi.json post /api/v1/families/stat-range/name Derives a name for a family range based on the range configuration. Nothing is persisted to the database. # GetFamilies Source: https://docs.siftstack.com/api-reference/familyservice/getfamilies /openapi.json post /api/v1/families:batchGet Retrieves the latest versions of multiple families. # GetFamily Source: https://docs.siftstack.com/api-reference/familyservice/getfamily /openapi.json get /api/v1/families/client_key/{clientKey} Retrieves the latest version of a family. # GetFamily Source: https://docs.siftstack.com/api-reference/familyservice/getfamily-1 /openapi.json get /api/v1/families/{familyId} Retrieves the latest version of a family. # GetFamilyCandidateRunCount Source: https://docs.siftstack.com/api-reference/familyservice/getfamilycandidateruncount /openapi.json get /api/v1/families/versions/{familyVersionId}/candidate-run-count Returns the count of candidate runs for a family version that are not already included or excluded. # GetFamilyCandidateRuns Source: https://docs.siftstack.com/api-reference/familyservice/getfamilycandidateruns /openapi.json get /api/v1/families/versions/{familyVersionId}/candidate-runs Retrieves the candidate runs for a family version based on the run query stored in the family version. # GetFamilyRuleDependencies Source: https://docs.siftstack.com/api-reference/familyservice/getfamilyruledependencies /openapi.json get /api/v1/families/{familyId}/rule-dependencies Retrieves all rules that reference the specified family across any of its stats. # GetFamilyStat Source: https://docs.siftstack.com/api-reference/familyservice/getfamilystat /openapi.json get /api/v1/family_stats/{familyStatId} Retrieves a family stat configuration. # GetFamilyStats Source: https://docs.siftstack.com/api-reference/familyservice/getfamilystats /openapi.json get /api/v1/family_stats/{familyVersionId} Retrieves family stats configurations for a family version. # GetFamilyVersion Source: https://docs.siftstack.com/api-reference/familyservice/getfamilyversion /openapi.json get /api/v1/families/versions/{familyVersionId} Retrieves a specific version of a family. # ImportFamily Source: https://docs.siftstack.com/api-reference/familyservice/importfamily /openapi.json post /api/v1/families:import Imports a new family from YAML. # ImportUpdateFamily Source: https://docs.siftstack.com/api-reference/familyservice/importupdatefamily /openapi.json patch /api/v1/families/client_key/{clientKey}/import-update Updates an existing family from YAML. # ImportUpdateFamily Source: https://docs.siftstack.com/api-reference/familyservice/importupdatefamily-1 /openapi.json patch /api/v1/families/{familyId}/import-update Updates an existing family from YAML. # ListFamilies Source: https://docs.siftstack.com/api-reference/familyservice/listfamilies /openapi.json get /api/v1/families Retrieves families using an optional filter. # ListFamilyAlignmentPoints Source: https://docs.siftstack.com/api-reference/familyservice/listfamilyalignmentpoints /openapi.json get /api/v1/families/alignments/{familyAlignmentId}/points Lists all alignment points for a specific family version alignment. # ListFamilyAlignments Source: https://docs.siftstack.com/api-reference/familyservice/listfamilyalignments /openapi.json get /api/v1/families/versions/{familyVersionId}/alignments Lists all alignments for a specific family version. # ListFamilyCandidateRuns Source: https://docs.siftstack.com/api-reference/familyservice/listfamilycandidateruns /openapi.json get /api/v1/families/candidate-runs Lists runs that match a candidate-run CEL filter. Supports `include_archived` as a CEL directive (archived runs are excluded by default; pass `include_archived == true` in the filter to include them). When `family_id` is provided, runs already on that family's persisted membership (both included and excluded) are filtered out so the response only contains runs not yet on the family. # ListFamilyMembers Source: https://docs.siftstack.com/api-reference/familyservice/listfamilymembers /openapi.json get /api/v1/families/versions/{familyVersionId}/members Lists all members of a family version. # ListFamilyVersions Source: https://docs.siftstack.com/api-reference/familyservice/listfamilyversions /openapi.json get /api/v1/families/versions Lists all versions of a family. # UpdateFamily Source: https://docs.siftstack.com/api-reference/familyservice/updatefamily /openapi.json patch /api/v1/families/client_key/{clientKey} Updates an existing family using the list of fields specified in `update_mask`. # UpdateFamily Source: https://docs.siftstack.com/api-reference/familyservice/updatefamily-1 /openapi.json patch /api/v1/families/{familyId} Updates an existing family using the list of fields specified in `update_mask`. # ValidateFamilyClientKey Source: https://docs.siftstack.com/api-reference/familyservice/validatefamilyclientkey /openapi.json post /api/v1/families:validateClientKey Used to validate whether or not a client key is valid. # ValidateFamilyName Source: https://docs.siftstack.com/api-reference/familyservice/validatefamilyname /openapi.json post /api/v1/families:validateFamilyName Used to validate whether or not a family name is valid. # CreateIngestionConfig Source: https://docs.siftstack.com/api-reference/ingestionconfigservice/createingestionconfig /openapi.json post /api/v1/ingestion-configs Create an ingestion config. # CreateIngestionConfig Source: https://docs.siftstack.com/api-reference/ingestionconfigservice/createingestionconfig-1 /openapi.json post /api/v2/ingestion-configs Create an ingestion config. # CreateIngestionConfigFlows Source: https://docs.siftstack.com/api-reference/ingestionconfigservice/createingestionconfigflows /openapi.json post /api/v1/ingestion-configs/{ingestionConfigId}/flows Create ingestion config flows. # CreateIngestionConfigFlows Source: https://docs.siftstack.com/api-reference/ingestionconfigservice/createingestionconfigflows-1 /openapi.json post /api/v2/ingestion-configs/{ingestionConfigId}/flows Create ingestion config flows. # GetIngestionConfig Source: https://docs.siftstack.com/api-reference/ingestionconfigservice/getingestionconfig /openapi.json get /api/v1/ingestion-configs/{ingestionConfigId} Retrieves an ingestion config. # GetIngestionConfig Source: https://docs.siftstack.com/api-reference/ingestionconfigservice/getingestionconfig-1 /openapi.json get /api/v2/ingestion-configs/{ingestionConfigId} Retrieves an ingestion config. # ListIngestionConfigFlows Source: https://docs.siftstack.com/api-reference/ingestionconfigservice/listingestionconfigflows /openapi.json get /api/v1/ingestion-configs/{ingestionConfigId}/flows List ingestion config flows using an optional filter. # ListIngestionConfigFlows Source: https://docs.siftstack.com/api-reference/ingestionconfigservice/listingestionconfigflows-1 /openapi.json get /api/v2/ingestion-configs/{ingestionConfigId}/flows List ingestion config flows using an optional filter. # ListIngestionConfigs Source: https://docs.siftstack.com/api-reference/ingestionconfigservice/listingestionconfigs /openapi.json get /api/v1/ingestion-configs List ingestion configs using an optional filter. # ListIngestionConfigs Source: https://docs.siftstack.com/api-reference/ingestionconfigservice/listingestionconfigs-1 /openapi.json get /api/v2/ingestion-configs List ingestion configs using an optional filter. # CancelJob Source: https://docs.siftstack.com/api-reference/jobservice/canceljob /openapi.json post /api/v1/jobs/{jobId}:cancel Requests cancellation of a job. # ListJobs Source: https://docs.siftstack.com/api-reference/jobservice/listjobs /openapi.json get /api/v1/jobs List jobs. # RetryJob Source: https://docs.siftstack.com/api-reference/jobservice/retryjob /openapi.json post /api/v1/jobs/{jobId}:retry Manually retries a job. # Get My User Information Source: https://docs.siftstack.com/api-reference/meservice/get-my-user-information /openapi.json get /api/v2/me Retrieve a user's information. # ArchiveMetadataKeys Source: https://docs.siftstack.com/api-reference/metadataservice/archivemetadatakeys /openapi.json post /api/v1/metadata-keys/archive Archive metadata keys. # ArchiveMetadataValues Source: https://docs.siftstack.com/api-reference/metadataservice/archivemetadatavalues /openapi.json post /api/v1/metadata-values/archive Archive metadata values. # Create a metadata value. Source: https://docs.siftstack.com/api-reference/metadataservice/create-a-metadata-value /openapi.json post /api/v1/metadata-values # CreateMetadataKey Source: https://docs.siftstack.com/api-reference/metadataservice/createmetadatakey /openapi.json post /api/v1/metadata-keys Create a metadata key. # DeleteMetadataKeys Source: https://docs.siftstack.com/api-reference/metadataservice/deletemetadatakeys /openapi.json post /api/v1/metadata-keys/delete Delete metadata keys. # DeleteMetadataValues Source: https://docs.siftstack.com/api-reference/metadataservice/deletemetadatavalues /openapi.json post /api/v1/metadata-values/delete Delete metadata values. # ListMetadataKeys Source: https://docs.siftstack.com/api-reference/metadataservice/listmetadatakeys /openapi.json get /api/v1/metadata-keys List metadata keys. # ListMetadataUsage Source: https://docs.siftstack.com/api-reference/metadataservice/listmetadatausage /openapi.json get /api/v1/metadata-key-usage List metadata key usage. # ListMetadataValues Source: https://docs.siftstack.com/api-reference/metadataservice/listmetadatavalues /openapi.json get /api/v1/metadata-values List metadata values. # UnarchiveMetadataKeys Source: https://docs.siftstack.com/api-reference/metadataservice/unarchivemetadatakeys /openapi.json post /api/v1/metadata-keys/unarchive Unarchive metadata keys. # UnarchiveMetadataValues Source: https://docs.siftstack.com/api-reference/metadataservice/unarchivemetadatavalues /openapi.json post /api/v1/metadata-values/unarchive Unarchive metadata values. # BatchUpdateNotifications Source: https://docs.siftstack.com/api-reference/notificationservice/batchupdatenotifications /openapi.json post /api/v1/notifications:batchUpdate Batch updates a list of notifications using the list of fields specified in their respective `update_mask`s. # ListNotifications Source: https://docs.siftstack.com/api-reference/notificationservice/listnotifications /openapi.json get /api/v1/notifications Retrieves notifications using an optional filter. # CreatePanelConfiguration Source: https://docs.siftstack.com/api-reference/panelconfigurationservice/createpanelconfiguration /openapi.json post /api/v1/panel-configurations Creates a panel configuration. # GetPanelConfiguration Source: https://docs.siftstack.com/api-reference/panelconfigurationservice/getpanelconfiguration /openapi.json get /api/v1/panel-configurations/{panelConfigurationId} Retrieves a panel configuration. # ListPanelConfigurations Source: https://docs.siftstack.com/api-reference/panelconfigurationservice/listpanelconfigurations /openapi.json get /api/v1/panel-configurations Retrieves panel configurations using an optional filter. # UpdatePanelConfiguration Source: https://docs.siftstack.com/api-reference/panelconfigurationservice/updatepanelconfiguration /openapi.json patch /api/v1/panel-configurations/{panelConfiguration.panelConfigurationId} Updates an existing panel configuration using using the list of fields specified in `update_mask`. # Get apiv1ping Source: https://docs.siftstack.com/api-reference/pingservice/get-apiv1ping /openapi.json get /api/v1/ping # ArchivePolicy Source: https://docs.siftstack.com/api-reference/policyservice/archivepolicy /openapi.json post /api/v1/policies/{policyId}/archive Archive a policy. # CreatePolicy Source: https://docs.siftstack.com/api-reference/policyservice/createpolicy /openapi.json post /api/v1/policies Create a new policy. # GetPolicy Source: https://docs.siftstack.com/api-reference/policyservice/getpolicy /openapi.json get /api/v1/policies/{policyId} Retrieve a policy. # ListPolicies Source: https://docs.siftstack.com/api-reference/policyservice/listpolicies /openapi.json get /api/v1/policies Retrieve policies using an optional filter. # UnarchivePolicy Source: https://docs.siftstack.com/api-reference/policyservice/unarchivepolicy /openapi.json post /api/v1/policies/{policyId}/unarchive Unarchive a previously-archived policy. # UpdatePolicy Source: https://docs.siftstack.com/api-reference/policyservice/updatepolicy /openapi.json patch /api/v1/policies Update a policy. # ValidatePolicy Source: https://docs.siftstack.com/api-reference/policyservice/validatepolicy /openapi.json post /api/v1/policies:validate Validate a Cedar policy configuration. # ArchivePrincipalAttributeEnumValue Source: https://docs.siftstack.com/api-reference/principalattributeservice/archiveprincipalattributeenumvalue /openapi.json post /api/v1/principal-attribute-enum-values/{archivedEnumValueId}/archive Archives a principal attribute enum value and migrates all principal attribute values with that enum value to a replacement enum value. # ArchivePrincipalAttributeKeys Source: https://docs.siftstack.com/api-reference/principalattributeservice/archiveprincipalattributekeys /openapi.json post /api/v1/principal-attribute-keys/archive Archive principal attribute keys. # ArchivePrincipalAttributeValues Source: https://docs.siftstack.com/api-reference/principalattributeservice/archiveprincipalattributevalues /openapi.json post /api/v1/principal-attribute-values/archive Archive principal attribute values. # BatchArchivePrincipalAttributeEnumValues Source: https://docs.siftstack.com/api-reference/principalattributeservice/batcharchiveprincipalattributeenumvalues /openapi.json post /api/v1/principal-attribute-enum-values/batch-archive Archives multiple principal attribute enum values and migrates all principal attribute values with those enum values to their respective replacement enum values. # BatchCreatePrincipalAttributeValue Source: https://docs.siftstack.com/api-reference/principalattributeservice/batchcreateprincipalattributevalue /openapi.json post /api/v1/principal-attribute-values/batch Creates a principal attribute value for multiple principals in a single operation. # BatchUnarchivePrincipalAttributeEnumValues Source: https://docs.siftstack.com/api-reference/principalattributeservice/batchunarchiveprincipalattributeenumvalues /openapi.json post /api/v1/principal-attribute-enum-values/batch-unarchive Unarchives multiple principal attribute enum values. # CheckPrincipalAttributeKeyArchiveImpact Source: https://docs.siftstack.com/api-reference/principalattributeservice/checkprincipalattributekeyarchiveimpact /openapi.json get /api/v1/principal-attribute-keys/{principalAttributeKeyId}/archive-impact Returns the count of active user principal-attribute values that would be archived with this key, and the count of active user-group principal-attribute value rows for this key (those rows stop contributing to evaluation once the key is archived). # CreatePrincipalAttributeEnumValue Source: https://docs.siftstack.com/api-reference/principalattributeservice/createprincipalattributeenumvalue /openapi.json post /api/v1/principal-attribute-enum-values Create a principal attribute enum value. # CreatePrincipalAttributeKey Source: https://docs.siftstack.com/api-reference/principalattributeservice/createprincipalattributekey /openapi.json post /api/v1/principal-attribute-keys Create a principal attribute key. # GetPrincipalAttributeEnumValue Source: https://docs.siftstack.com/api-reference/principalattributeservice/getprincipalattributeenumvalue /openapi.json get /api/v1/principal-attribute-enum-values/{principalAttributeEnumValueId} Retrieves a principal attribute enum value. # GetPrincipalAttributeKey Source: https://docs.siftstack.com/api-reference/principalattributeservice/getprincipalattributekey /openapi.json get /api/v1/principal-attribute-keys/{principalAttributeKeyId} Retrieves a principal attribute key. # GetPrincipalAttributeValue Source: https://docs.siftstack.com/api-reference/principalattributeservice/getprincipalattributevalue /openapi.json get /api/v1/principal-attribute-values/{principalAttributeValueId} Retrieves a principal attribute value. # ListPrincipalAttributeEnumValues Source: https://docs.siftstack.com/api-reference/principalattributeservice/listprincipalattributeenumvalues /openapi.json get /api/v1/principal-attribute-keys/{principalAttributeKeyId}/enum-values Lists principal attribute enum values for a given principal attribute key. # ListPrincipalAttributeKeys Source: https://docs.siftstack.com/api-reference/principalattributeservice/listprincipalattributekeys /openapi.json get /api/v1/principal-attribute-keys Lists principal attribute keys. # ListPrincipalAttributeKeyValues Source: https://docs.siftstack.com/api-reference/principalattributeservice/listprincipalattributekeyvalues /openapi.json get /api/v1/principal-attribute-keys/{principalAttributeKeyId}/principal-attribute-values Lists principal attribute values for a given principal attribute key. # ListPrincipalAttributeValues Source: https://docs.siftstack.com/api-reference/principalattributeservice/listprincipalattributevalues /openapi.json get /api/v1/principal-attribute-values Lists principal attribute values. # UnarchivePrincipalAttributeEnumValue Source: https://docs.siftstack.com/api-reference/principalattributeservice/unarchiveprincipalattributeenumvalue /openapi.json post /api/v1/principal-attribute-enum-values/{principalAttributeEnumValueId}/unarchive Unarchives a principal attribute enum value. # UnarchivePrincipalAttributeKeys Source: https://docs.siftstack.com/api-reference/principalattributeservice/unarchiveprincipalattributekeys /openapi.json post /api/v1/principal-attribute-keys/unarchive Unarchive principal attribute keys. # UnarchivePrincipalAttributeValues Source: https://docs.siftstack.com/api-reference/principalattributeservice/unarchiveprincipalattributevalues /openapi.json post /api/v1/principal-attribute-values/unarchive Unarchive principal attribute values. # UpdatePrincipalAttributeEnumValue Source: https://docs.siftstack.com/api-reference/principalattributeservice/updateprincipalattributeenumvalue /openapi.json patch /api/v1/principal-attribute-enum-values/{principalAttributeEnumValueId} Updates an existing principal attribute enum value. # UpdatePrincipalAttributeKey Source: https://docs.siftstack.com/api-reference/principalattributeservice/updateprincipalattributekey /openapi.json patch /api/v1/principal-attribute-keys/{principalAttributeKeyId} Updates an existing principal attribute key. # AddProtobufDescriptor Source: https://docs.siftstack.com/api-reference/protobufdescriptorservice/addprotobufdescriptor /openapi.json post /api/v1/protobuf-descriptors:add Used to register a protobuf message to be ingested. # AddProtobufDescriptor Source: https://docs.siftstack.com/api-reference/protobufdescriptorservice/addprotobufdescriptor-1 /openapi.json post /api/v2/protobuf-descriptors:add Used to register a protobuf message to be ingested. # CheckProtobufDescriptorCompatibility Source: https://docs.siftstack.com/api-reference/protobufdescriptorservice/checkprotobufdescriptorcompatibility /openapi.json post /api/v2/protobuf-descriptors:check-compatibility Used to check if a protobuf descriptor is compatible with the existing descriptors. # DeleteProtobufDescriptors Source: https://docs.siftstack.com/api-reference/protobufdescriptorservice/deleteprotobufdescriptors /openapi.json delete /api/v1/protobuf-descriptors Delete protobuf descriptors of that match the provided `namespace` and `message_type_full_name`. # DeleteProtobufDescriptors Source: https://docs.siftstack.com/api-reference/protobufdescriptorservice/deleteprotobufdescriptors-1 /openapi.json delete /api/v2/protobuf-descriptors Delete protobuf descriptors of that match the provided `namespace` and `message_type_full_name`. # ListProtobufDescriptors Source: https://docs.siftstack.com/api-reference/protobufdescriptorservice/listprotobufdescriptors /openapi.json get /api/v1/protobuf-descriptors Retrieve protobuf descriptors using an optional filter. # ListProtobufDescriptors Source: https://docs.siftstack.com/api-reference/protobufdescriptorservice/listprotobufdescriptors-1 /openapi.json get /api/v2/protobuf-descriptors Retrieve protobuf descriptors using an optional filter. # BatchDeleteRemoteFiles Source: https://docs.siftstack.com/api-reference/remotefileservice/batchdeleteremotefiles /openapi.json post /api/v1/remote-files:batchDelete Batch delete remote files. Each batch is limited to 1000 records. # CreateRemoteFile Source: https://docs.siftstack.com/api-reference/remotefileservice/createremotefile /openapi.json post /api/v1/remote-files Create a remote file. # DeleteRemoteFile Source: https://docs.siftstack.com/api-reference/remotefileservice/deleteremotefile /openapi.json delete /api/v1/remote-files/{remoteFileId} Delete a remote file. # GetRemoteFile Source: https://docs.siftstack.com/api-reference/remotefileservice/getremotefile /openapi.json get /api/v1/remote-files/{remoteFileId} Retrieve a remote file. # GetRemoteFileUrl Source: https://docs.siftstack.com/api-reference/remotefileservice/getremotefileurl /openapi.json get /api/v1/remote-files/{remoteFileId}/download-url Gets a download URL for the remote file. # ListRemoteFiles Source: https://docs.siftstack.com/api-reference/remotefileservice/listremotefiles /openapi.json get /api/v1/remote-files List remote files. # UpdateRemoteFile Source: https://docs.siftstack.com/api-reference/remotefileservice/updateremotefile /openapi.json patch /api/v1/remote-files Updates an existing remote file using using the list of fields specified in `update_mask`. # CancelReport Source: https://docs.siftstack.com/api-reference/reportservice/cancelreport /openapi.json post /api/v1/reports/{reportId}:cancel Canceling a report will stop the evaluation of the report and mark it as canceled. Any results that have been calculated up to the point of cancellation will be saved. # CreateReport Source: https://docs.siftstack.com/api-reference/reportservice/createreport /openapi.json post /api/v1/reports Create a report. # GetReport Source: https://docs.siftstack.com/api-reference/reportservice/getreport /openapi.json get /api/v1/reports/{reportId} Retrieve a report. # ListReportMetadataValues Source: https://docs.siftstack.com/api-reference/reportservice/listreportmetadatavalues /openapi.json get /api/v1/reports/{reportId}/metadata-values List paginated metadata values for a specific report. # ListReportRuleSummaries Source: https://docs.siftstack.com/api-reference/reportservice/listreportrulesummaries /openapi.json get /api/v1/reports/{reportId}/rule-summaries List paginated rule summaries for a specific report. # ListReports Source: https://docs.siftstack.com/api-reference/reportservice/listreports /openapi.json get /api/v1/reports List reports. # ListReportsWithCumulativeSummary Source: https://docs.siftstack.com/api-reference/reportservice/listreportswithcumulativesummary /openapi.json get /api/v1/reports:with-cumulative-summary List reports with cumulative summary. # RerunReport Source: https://docs.siftstack.com/api-reference/reportservice/rerunreport /openapi.json post /api/v1/reports/{reportId}:rerun Rerunning a report will create a new report with the same rule versions and run as the original report and run the evaluation again using the most up-to-date set of data. # UpdateReport Source: https://docs.siftstack.com/api-reference/reportservice/updatereport /openapi.json put /api/v1/reports Update a report. # CreateReportTemplate Source: https://docs.siftstack.com/api-reference/reporttemplateservice/createreporttemplate /openapi.json post /api/v1/report-templates Create a report template. # GetReportTemplate Source: https://docs.siftstack.com/api-reference/reporttemplateservice/getreporttemplate /openapi.json get /api/v1/report-templates/{reportTemplateId} Retrieve a report template. # GetReportTemplate Source: https://docs.siftstack.com/api-reference/reporttemplateservice/getreporttemplate-1 /openapi.json get /v1/organizations/{organizationId}/report_templates/{clientKey} Retrieve a report template. # ListReportTemplates Source: https://docs.siftstack.com/api-reference/reporttemplateservice/listreporttemplates /openapi.json get /api/v1/report-templates List report templates. # UpdateReportTemplate Source: https://docs.siftstack.com/api-reference/reporttemplateservice/updatereporttemplate /openapi.json patch /api/v1/report-templates Updates an existing report template using the list of fields specified in `update_mask`. # Archives a resource_attribute key AND all its associated enum values AND all its associated resource-attributes. Source: https://docs.siftstack.com/api-reference/resourceattributeservice/archives-a-resource_attribute-key-and-all-its-associated-enum-values-and-all-its-associated-resource-attributes /openapi.json post /api/v1/resource-attribute-keys/{resourceAttributeKeyId}/archive # Archives an enum value and migrates all resource-attributes with that value to a replacement value. Source: https://docs.siftstack.com/api-reference/resourceattributeservice/archives-an-enum-value-and-migrates-all-resource-attributes-with-that-value-to-a-replacement-value /openapi.json post /api/v1/resource-attribute-enum-values/{archivedEnumValueId}/archive # Archives multiple enum values and migrates all resource-attributes with those values to their respective replacement values. Source: https://docs.siftstack.com/api-reference/resourceattributeservice/archives-multiple-enum-values-and-migrates-all-resource-attributes-with-those-values-to-their-respective-replacement-values /openapi.json post /api/v1/resource-attribute-enum-values/batch-archive # Archives multiple resource-attributes. Source: https://docs.siftstack.com/api-reference/resourceattributeservice/archives-multiple-resource-attributes /openapi.json post /api/v1/resource-attributes/batch-archive # Archives multiple resource_attribute keys AND all their associated enum values AND all their associated resource-attributes. Source: https://docs.siftstack.com/api-reference/resourceattributeservice/archives-multiple-resource_attribute-keys-and-all-their-associated-enum-values-and-all-their-associated-resource-attributes /openapi.json post /api/v1/resource-attribute-keys/batch-archive # Batch lists all resource-attributes for multiple entities. Excludes archived by default. Source: https://docs.siftstack.com/api-reference/resourceattributeservice/batch-lists-all-resource-attributes-for-multiple-entities-excludes-archived-by-default /openapi.json post /api/v1/entities/batch-resource-attributes # Creates resource-attributes for multiple entities with the same key-value pair. Source: https://docs.siftstack.com/api-reference/resourceattributeservice/creates-resource-attributes-for-multiple-entities-with-the-same-key-value-pair /openapi.json post /api/v1/resource-attributes/batch # Get apiv1resource attribute enum values Source: https://docs.siftstack.com/api-reference/resourceattributeservice/get-apiv1resource-attribute-enum-values /openapi.json get /api/v1/resource-attribute-enum-values/{resourceAttributeEnumValueId} # Get apiv1resource attribute keys Source: https://docs.siftstack.com/api-reference/resourceattributeservice/get-apiv1resource-attribute-keys /openapi.json get /api/v1/resource-attribute-keys # Get apiv1resource attribute keys 1 Source: https://docs.siftstack.com/api-reference/resourceattributeservice/get-apiv1resource-attribute-keys-1 /openapi.json get /api/v1/resource-attribute-keys/{resourceAttributeKeyId} # Get apiv1resource attribute keys archive impact Source: https://docs.siftstack.com/api-reference/resourceattributeservice/get-apiv1resource-attribute-keys-archive-impact /openapi.json get /api/v1/resource-attribute-keys/{resourceAttributeKeyId}/archive-impact # Get apiv1resource attribute keys enum values Source: https://docs.siftstack.com/api-reference/resourceattributeservice/get-apiv1resource-attribute-keys-enum-values /openapi.json get /api/v1/resource-attribute-keys/{resourceAttributeKeyId}/enum-values # Get apiv1resource attributes Source: https://docs.siftstack.com/api-reference/resourceattributeservice/get-apiv1resource-attributes /openapi.json get /api/v1/resource-attributes # Get apiv1resource attributes 1 Source: https://docs.siftstack.com/api-reference/resourceattributeservice/get-apiv1resource-attributes-1 /openapi.json get /api/v1/resource-attributes/{resourceAttributeId} # Lists all resource-attributes for a specific entity. Excludes archived by default. Source: https://docs.siftstack.com/api-reference/resourceattributeservice/lists-all-resource-attributes-for-a-specific-entity-excludes-archived-by-default /openapi.json get /api/v1/entities/{entity.entityId}/resource-attributes # Patch apiv1resource attribute enum values Source: https://docs.siftstack.com/api-reference/resourceattributeservice/patch-apiv1resource-attribute-enum-values /openapi.json patch /api/v1/resource-attribute-enum-values/{resourceAttributeEnumValueId} # Patch apiv1resource attribute keys Source: https://docs.siftstack.com/api-reference/resourceattributeservice/patch-apiv1resource-attribute-keys /openapi.json patch /api/v1/resource-attribute-keys/{resourceAttributeKeyId} # Post apiv1resource attribute enum values Source: https://docs.siftstack.com/api-reference/resourceattributeservice/post-apiv1resource-attribute-enum-values /openapi.json post /api/v1/resource-attribute-enum-values # Post apiv1resource attribute keys Source: https://docs.siftstack.com/api-reference/resourceattributeservice/post-apiv1resource-attribute-keys /openapi.json post /api/v1/resource-attribute-keys # Post apiv1resource attributes archive Source: https://docs.siftstack.com/api-reference/resourceattributeservice/post-apiv1resource-attributes-archive /openapi.json post /api/v1/resource-attributes/{resourceAttributeId}/archive # Post apiv1resource attributes unarchive Source: https://docs.siftstack.com/api-reference/resourceattributeservice/post-apiv1resource-attributes-unarchive /openapi.json post /api/v1/resource-attributes/{resourceAttributeId}/unarchive # Unarchives a resource_attribute key BUT NOT its associated enum values OR resource-attributes. Source: https://docs.siftstack.com/api-reference/resourceattributeservice/unarchives-a-resource_attribute-key-but-not-its-associated-enum-values-or-resource-attributes /openapi.json post /api/v1/resource-attribute-keys/{resourceAttributeKeyId}/unarchive # Unarchives an enum value BUT DOES NOT migrate resource-attributes with a replacement value back to the original value. Source: https://docs.siftstack.com/api-reference/resourceattributeservice/unarchives-an-enum-value-but-does-not-migrate-resource-attributes-with-a-replacement-value-back-to-the-original-value /openapi.json post /api/v1/resource-attribute-enum-values/{resourceAttributeEnumValueId}/unarchive # Unarchives multiple enum values BUT DOES NOT migrate resource-attributes with a replacement value back to the original value. Source: https://docs.siftstack.com/api-reference/resourceattributeservice/unarchives-multiple-enum-values-but-does-not-migrate-resource-attributes-with-a-replacement-value-back-to-the-original-value /openapi.json post /api/v1/resource-attribute-enum-values/batch-unarchive # Unarchives multiple resource-attributes. Source: https://docs.siftstack.com/api-reference/resourceattributeservice/unarchives-multiple-resource-attributes /openapi.json post /api/v1/resource-attributes/batch-unarchive # Unarchives multiple resource_attribute keys BUT NOT their associated enum values OR resource-attributes. Source: https://docs.siftstack.com/api-reference/resourceattributeservice/unarchives-multiple-resource_attribute-keys-but-not-their-associated-enum-values-or-resource-attributes /openapi.json post /api/v1/resource-attribute-keys/batch-unarchive # ListRoles Source: https://docs.siftstack.com/api-reference/roleservice/listroles /openapi.json get /api/v2/roles Retrieves roles using an optional filter. # EvaluateRules Source: https://docs.siftstack.com/api-reference/ruleevaluationservice/evaluaterules /openapi.json post /api/v1/rules/evaluate-rules Evaluate rules from a designated source against a run or asset and return the total amount of annotations created and the ID of the generated report. # EvaluateRulesPreview Source: https://docs.siftstack.com/api-reference/ruleevaluationservice/evaluaterulespreview /openapi.json post /api/v1/rules/evaluate-rules:preview Perform a dry run evaluation for existing rules or rule configurations against a run and return the annotations that would be generated. # ArchiveRule Source: https://docs.siftstack.com/api-reference/ruleservice/archiverule /openapi.json post /api/v1/rules/archive Archives a rule. # BatchArchiveRules Source: https://docs.siftstack.com/api-reference/ruleservice/batcharchiverules /openapi.json post /api/v1/rules/batchArchive Batch archives rules. # BatchDeleteRules Source: https://docs.siftstack.com/api-reference/ruleservice/batchdeleterules /openapi.json post /api/v1/rules/batchDelete Archives multiple rules. Deprecated: Use BatchArchiveRules instead. # BatchGetRules Source: https://docs.siftstack.com/api-reference/ruleservice/batchgetrules /openapi.json post /api/v1/rules:batchGet Retrieves multiple rules. # BatchGetRuleVersions Source: https://docs.siftstack.com/api-reference/ruleservice/batchgetruleversions /openapi.json post /api/v1/rules:batchGetVersions Retrieves multiple rules by rule versions. # BatchUnarchiveRules Source: https://docs.siftstack.com/api-reference/ruleservice/batchunarchiverules /openapi.json post /api/v1/rules/batchUnarchive Batch unarchives rules. # BatchUndeleteRules Source: https://docs.siftstack.com/api-reference/ruleservice/batchundeleterules /openapi.json post /api/v1/rules/batchUndelete Deprecated: Use BatchUnarchiveRules instead. # BatchUpdateRules Source: https://docs.siftstack.com/api-reference/ruleservice/batchupdaterules /openapi.json put /api/v1/rules:batchUpdate Updates existing rules or creates rules that do not exist. # CreateRule Source: https://docs.siftstack.com/api-reference/ruleservice/createrule /openapi.json post /api/v1/rules Creates a rule. # DeleteRule Source: https://docs.siftstack.com/api-reference/ruleservice/deleterule /openapi.json post /api/v1/rules/delete Archives a rule. Deprecated: Use ArchiveRule instead. # EvaluateRules Source: https://docs.siftstack.com/api-reference/ruleservice/evaluaterules /openapi.json post /api/v1/rules/evaluate Evaluates the provided rules and generate annotations based on the result. # GetRule Source: https://docs.siftstack.com/api-reference/ruleservice/getrule /openapi.json get /api/v1/rules Retrieves the latest version of a rule. # GetRuleVersion Source: https://docs.siftstack.com/api-reference/ruleservice/getruleversion /openapi.json get /api/v1/rules:version Retrieves a specific version of a rule. # ListRules Source: https://docs.siftstack.com/api-reference/ruleservice/listrules /openapi.json get /api/v1/rules:list Retrieves a list of rules. # ListRuleVersions Source: https://docs.siftstack.com/api-reference/ruleservice/listruleversions /openapi.json get /api/v1/rules/{ruleId}/versions Retrieves a list of rule versions for the given rule. # SearchRules Source: https://docs.siftstack.com/api-reference/ruleservice/searchrules /openapi.json post /api/v1/rules/search Queries rules based on provided search parameters. # UnarchiveRule Source: https://docs.siftstack.com/api-reference/ruleservice/unarchiverule /openapi.json post /api/v1/rules/unarchive Unarchives a rule. # UndeleteRule Source: https://docs.siftstack.com/api-reference/ruleservice/undeleterule /openapi.json post /api/v1/rules/undelete Deprecated: Use UnarchiveRule instead. # UpdateHumanFriendlyRules Source: https://docs.siftstack.com/api-reference/ruleservice/updatehumanfriendlyrules /openapi.json post /api/v1/rules:updateHumanFriendly Batch update rules given the `rules_json` which is a JSON list of rules. # UpdateJsonRules Source: https://docs.siftstack.com/api-reference/ruleservice/updatejsonrules /openapi.json post /api/v1/rules:updateJson Batch update rules given the `rules_json` which is a JSON list of rules. # UpdateRule Source: https://docs.siftstack.com/api-reference/ruleservice/updaterule /openapi.json put /api/v1/rules Updates an existing rule. # ValidateJsonRules Source: https://docs.siftstack.com/api-reference/ruleservice/validatejsonrules /openapi.json post /api/v1/rules:validateJson Validate a batch update for rules given the `rules_json` which is a JSON list of rules. # ViewHumanFriendlyRules Source: https://docs.siftstack.com/api-reference/ruleservice/viewhumanfriendlyrules /openapi.json get /api/v1/rules:viewHumanFriendly Retrieve a JSON object containing all of the rules for a given asset. # ViewJsonRules Source: https://docs.siftstack.com/api-reference/ruleservice/viewjsonrules /openapi.json get /api/v1/rules:viewJson Retrieve a JSON object containing all of the rules for a given asset. # CreateAdhocRun Source: https://docs.siftstack.com/api-reference/runservice/createadhocrun /openapi.json post /api/v2/runs:adhoc Create an adhoc run. # CreateAutomaticRunAssociationForAssets Source: https://docs.siftstack.com/api-reference/runservice/createautomaticrunassociationforassets /openapi.json post /api/v2/runs/{runId}:create-automatic-run-association-for-assets Associates a list of assets with a given run. # CreateRun Source: https://docs.siftstack.com/api-reference/runservice/createrun /openapi.json post /api/v2/runs Create a run. # DeleteRun Source: https://docs.siftstack.com/api-reference/runservice/deleterun /openapi.json delete /api/v2/runs/{runId} Permanently delete a given run. Deprecated: Use update with is_archived. # GetRun Source: https://docs.siftstack.com/api-reference/runservice/getrun /openapi.json get /api/v2/runs/{runId} Retrieve a run. # ListRuns Source: https://docs.siftstack.com/api-reference/runservice/listruns /openapi.json get /api/v2/runs Retrieve runs using an optional filter. # StopRun Source: https://docs.siftstack.com/api-reference/runservice/stoprun /openapi.json patch /api/v2/runs:stop Set the stop time of a run to the current time. To set the stop time of a run to an arbitrary time see `UpdateRun`. # UpdateRun Source: https://docs.siftstack.com/api-reference/runservice/updaterun /openapi.json patch /api/v2/runs Updates an existing run using using the list of fields specified in `update_mask`. # ValidateRunFilter Source: https://docs.siftstack.com/api-reference/runservice/validaterunfilter /openapi.json post /api/v2/runs:validateFilter Validates a CEL filter expression against the available run filter fields. # BatchDeleteSavedSearches Source: https://docs.siftstack.com/api-reference/savedsearchservice/batchdeletesavedsearches /openapi.json post /api/v1/saved_searches:batchDelete Batch delete saved searches. # CreateSavedSearch Source: https://docs.siftstack.com/api-reference/savedsearchservice/createsavedsearch /openapi.json post /api/v1/saved_searches Create a saved search. # DeleteSavedSearch Source: https://docs.siftstack.com/api-reference/savedsearchservice/deletesavedsearch /openapi.json delete /api/v1/saved_searches/{savedSearchId} Delete a saved search. # GetSavedSearch Source: https://docs.siftstack.com/api-reference/savedsearchservice/getsavedsearch /openapi.json get /api/v1/saved_searches/{savedSearchId} Retrieve a saved search. # ListSavedSearches Source: https://docs.siftstack.com/api-reference/savedsearchservice/listsavedsearches /openapi.json get /api/v1/saved_searches List saved searches. # UpdateSavedSearch Source: https://docs.siftstack.com/api-reference/savedsearchservice/updatesavedsearch /openapi.json patch /api/v1/saved_searches Updates an existing saved search using using the list of fields specified in `update_mask`. # CreateTag Source: https://docs.siftstack.com/api-reference/tagservice/createtag /openapi.json post /api/v1/tags Create a tag. # CreateTag Source: https://docs.siftstack.com/api-reference/tagservice/createtag-1 /openapi.json post /api/v2/tags Create a tag. # ListTags Source: https://docs.siftstack.com/api-reference/tagservice/listtags /openapi.json get /api/v1/tags Retrieves tags using an optional filter. # ListTags Source: https://docs.siftstack.com/api-reference/tagservice/listtags-1 /openapi.json get /api/v2/tags Retrieves tags using an optional filter. # CountTestMeasurements Source: https://docs.siftstack.com/api-reference/testreportservice/counttestmeasurements /openapi.json get /api/v1/test-measurements/count Counts test measurements with optional filtering # CountTestSteps Source: https://docs.siftstack.com/api-reference/testreportservice/countteststeps /openapi.json get /api/v1/test-steps/count Counts test steps with optional filtering # CreateTestMeasurement Source: https://docs.siftstack.com/api-reference/testreportservice/createtestmeasurement /openapi.json post /api/v1/test-measurements Creates a test measurement # CreateTestMeasurements Source: https://docs.siftstack.com/api-reference/testreportservice/createtestmeasurements /openapi.json post /api/v1/test-measurements:batch Creates multiple test measurements in a single request # CreateTestReport Source: https://docs.siftstack.com/api-reference/testreportservice/createtestreport /openapi.json post /api/v1/test-reports Creates a test report # CreateTestStep Source: https://docs.siftstack.com/api-reference/testreportservice/createteststep /openapi.json post /api/v1/test-steps Creates a test step # DeleteTestMeasurement Source: https://docs.siftstack.com/api-reference/testreportservice/deletetestmeasurement /openapi.json delete /api/v1/test-measurements/{measurementId} Deletes a test measurement # DeleteTestReport Source: https://docs.siftstack.com/api-reference/testreportservice/deletetestreport /openapi.json delete /api/v1/test-reports/{testReportId} Deletes a test report # DeleteTestStep Source: https://docs.siftstack.com/api-reference/testreportservice/deleteteststep /openapi.json delete /api/v1/test-steps/{testStepId} Deletes a test step # GetTestReport Source: https://docs.siftstack.com/api-reference/testreportservice/gettestreport /openapi.json get /api/v1/test-reports/{testReportId} Gets a single test report # ImportTestReport Source: https://docs.siftstack.com/api-reference/testreportservice/importtestreport /openapi.json post /api/v1/test-reports:import Imports a test report from an already-uploaded file. # ListTestMeasurements Source: https://docs.siftstack.com/api-reference/testreportservice/listtestmeasurements /openapi.json get /api/v1/test-measurements Lists test measurements with optional filtering # ListTestReports Source: https://docs.siftstack.com/api-reference/testreportservice/listtestreports /openapi.json get /api/v1/test-reports Lists test reports with optional filtering # ListTestSteps Source: https://docs.siftstack.com/api-reference/testreportservice/listteststeps /openapi.json get /api/v1/test-steps Lists test steps with optional filtering # UpdateTestMeasurement Source: https://docs.siftstack.com/api-reference/testreportservice/updatetestmeasurement /openapi.json patch /api/v1/test-measurements Updates a test measurement # UpdateTestReport Source: https://docs.siftstack.com/api-reference/testreportservice/updatetestreport /openapi.json patch /api/v1/test-reports Updates a test report # UpdateTestStep Source: https://docs.siftstack.com/api-reference/testreportservice/updateteststep /openapi.json patch /api/v1/test-steps Updates a test step # CreateUnit Source: https://docs.siftstack.com/api-reference/unitservice/createunit /openapi.json post /api/v2/units Used to create a unit. # ListUnits Source: https://docs.siftstack.com/api-reference/unitservice/listunits /openapi.json get /api/v2/units Used to list units. # CheckUpdatableFields Source: https://docs.siftstack.com/api-reference/userdefinedfunctionservice/checkupdatablefields /openapi.json post /api/v1/user-defined-functions/updatable-fields Check if given update paths are allowed to update for the user defined function # CreateUserDefinedFunction Source: https://docs.siftstack.com/api-reference/userdefinedfunctionservice/createuserdefinedfunction /openapi.json post /api/v1/user-defined-functions Create a user defined function. # GetUserDefinedFunction Source: https://docs.siftstack.com/api-reference/userdefinedfunctionservice/getuserdefinedfunction /openapi.json get /api/v1/user-defined-functions/{userDefinedFunctionId} Retrieve the latest version of a user defined function. # GetUserDefinedFunctionDependents Source: https://docs.siftstack.com/api-reference/userdefinedfunctionservice/getuserdefinedfunctiondependents /openapi.json get /api/v1/user-defined-functions/dependents Retrieve dependents of a user defined function. # GetUserDefinedFunctionVersion Source: https://docs.siftstack.com/api-reference/userdefinedfunctionservice/getuserdefinedfunctionversion /openapi.json get /api/v1/user-defined-functions/versions/{userDefinedFunctionVersionId} Retrieve a specific version of a user defined function. # GetUserDefinedFunctionVersions Source: https://docs.siftstack.com/api-reference/userdefinedfunctionservice/getuserdefinedfunctionversions /openapi.json get /api/v1/user-defined-functions/versions Retrieve versions of user defined functions. # ListUserDefinedFunctions Source: https://docs.siftstack.com/api-reference/userdefinedfunctionservice/listuserdefinedfunctions /openapi.json get /api/v1/user-defined-functions Retrieve the latest versions of user defined functions based on an optional filter. # ListUserDefinedFunctionVersions Source: https://docs.siftstack.com/api-reference/userdefinedfunctionservice/listuserdefinedfunctionversions /openapi.json get /api/v1/user-defined-functions/{userDefinedFunctionId}/versions List versions of a particular user defined function with an optional filter. # UpdateUserDefinedFunction Source: https://docs.siftstack.com/api-reference/userdefinedfunctionservice/updateuserdefinedfunction /openapi.json patch /api/v1/user-defined-functions Update and create a new version of a user defined function. # ValidateUserDefinedFunction Source: https://docs.siftstack.com/api-reference/userdefinedfunctionservice/validateuserdefinedfunction /openapi.json post /api/v1/user-defined-functions:validate Validates a potential user defined function. # AddUserToUserGroup Source: https://docs.siftstack.com/api-reference/usergroupservice/addusertousergroup /openapi.json post /api/v2/user-groups:add-user Adds a user to a user group. # CreateUserGroup Source: https://docs.siftstack.com/api-reference/usergroupservice/createusergroup /openapi.json post /api/v2/user-groups Creates a user group. # DeleteUserGroup Source: https://docs.siftstack.com/api-reference/usergroupservice/deleteusergroup /openapi.json delete /api/v2/user-groups/{userGroupId} Deletes a user group. # GetUserGroup Source: https://docs.siftstack.com/api-reference/usergroupservice/getusergroup /openapi.json get /api/v2/user-groups/{userGroupId} Retrieves a user group. # GetUserGroupsForAssets Source: https://docs.siftstack.com/api-reference/usergroupservice/getusergroupsforassets /openapi.json get /api/v2/user-groups:get-for-assets Retrieves user groups for a list of assets. # ListUserGroups Source: https://docs.siftstack.com/api-reference/usergroupservice/listusergroups /openapi.json get /api/v2/user-groups Retrieves user groups using an optional filter. # RemoveUserFromUserGroup Source: https://docs.siftstack.com/api-reference/usergroupservice/removeuserfromusergroup /openapi.json post /api/v2/user-groups:remove-user Removes a user from a user group. # UpdateUserGroup Source: https://docs.siftstack.com/api-reference/usergroupservice/updateusergroup /openapi.json patch /api/v2/user-groups/{userGroup.userGroupId} Updates a user group. # UpdateUserUserGroups Source: https://docs.siftstack.com/api-reference/usergroupservice/updateuserusergroups /openapi.json post /api/v2/user-groups:update-user Updates a user's user groups. # GetUser Source: https://docs.siftstack.com/api-reference/userservice/getuser /openapi.json get /api/v2/users/{userId} Retrieves a user object. # ListActiveUsers Source: https://docs.siftstack.com/api-reference/userservice/listactiveusers /openapi.json get /api/v2/users List active users. # ListUsers Source: https://docs.siftstack.com/api-reference/userservice/listusers /openapi.json get /api/v2/users:all List users. # UpdateUserOrganizationActive Source: https://docs.siftstack.com/api-reference/userservice/updateuserorganizationactive /openapi.json post /api/v2/users/{userId}/active Used to toggle a user's active status within their organization. # CreateView Source: https://docs.siftstack.com/api-reference/viewservice/createview /openapi.json post /api/v1/views Creates a view. # CreateView Source: https://docs.siftstack.com/api-reference/viewservice/createview-1 /openapi.json post /api/v2/views Creates a view. # DeleteView Source: https://docs.siftstack.com/api-reference/viewservice/deleteview /openapi.json delete /api/v1/views/{viewId} Deletes a view. # DeleteView Source: https://docs.siftstack.com/api-reference/viewservice/deleteview-1 /openapi.json delete /api/v2/views/{viewId} Deletes a view. # GetView Source: https://docs.siftstack.com/api-reference/viewservice/getview /openapi.json get /api/v1/views/{viewId} Retrieves a view. # GetView Source: https://docs.siftstack.com/api-reference/viewservice/getview-1 /openapi.json get /api/v2/views/{viewId} Retrieves a view. # ListApplicableViews Source: https://docs.siftstack.com/api-reference/viewservice/listapplicableviews /openapi.json get /api/v2/views:applicable Lists views that apply to assets/runs. # Lists views that apply to assets/runs. Source: https://docs.siftstack.com/api-reference/viewservice/lists-views-that-apply-to-assetsruns /openapi.json get /api/v1/views:applicable # ListViews Source: https://docs.siftstack.com/api-reference/viewservice/listviews /openapi.json get /api/v1/views Retrieves views using an optional filter. # ListViews Source: https://docs.siftstack.com/api-reference/viewservice/listviews-1 /openapi.json get /api/v2/views Retrieves views using an optional filter. # PinView Source: https://docs.siftstack.com/api-reference/viewservice/pinview /openapi.json patch /api/v1/views/{viewId}/pin Pins a view. # PinView Source: https://docs.siftstack.com/api-reference/viewservice/pinview-1 /openapi.json patch /api/v2/views/{viewId}/pin Pins a view. # UnpinView Source: https://docs.siftstack.com/api-reference/viewservice/unpinview /openapi.json patch /api/v1/views/{viewId}/unpin Unpins a view. # UnpinView Source: https://docs.siftstack.com/api-reference/viewservice/unpinview-1 /openapi.json patch /api/v2/views/{viewId}/unpin Unpins a view. # UpdateView Source: https://docs.siftstack.com/api-reference/viewservice/updateview /openapi.json patch /api/v1/views/{view.viewId} Updates an existing view using using the list of fields specified in `update_mask`. # UpdateView Source: https://docs.siftstack.com/api-reference/viewservice/updateview-1 /openapi.json patch /api/v2/views/{view.viewId} Updates an existing view using using the list of fields specified in `update_mask`. # BatchCreateWebhookLogs Source: https://docs.siftstack.com/api-reference/webhookservice/batchcreatewebhooklogs /openapi.json post /api/v1/webhooks/logs:batch-create Create a batch of webhook logs. Users should not have to call this directly. # CreateOrUpdateWebhookSignatureKey Source: https://docs.siftstack.com/api-reference/webhookservice/createorupdatewebhooksignaturekey /openapi.json post /api/v1/webhooks/signature-key Create a webhook signature key and set its activation state. If a webhook signature key is active, the bodies of all webhooks will be signed using the signature key with HMAC-SHA-256.The signature generated will then included in the `X-Sift-Signature` HTTP header. Only one key can be held per organization. If an existing key exists, then this will simply return it.See `WebhookService_RotateWebhookSignatureKey` to rotate the key. # CreateWebhook Source: https://docs.siftstack.com/api-reference/webhookservice/createwebhook /openapi.json post /api/v1/webhooks Create a webhook. # GetWebhook Source: https://docs.siftstack.com/api-reference/webhookservice/getwebhook /openapi.json get /api/v1/webhooks/{webhookId} Retrieve a webhook by ID. # GetWebhookSignatureKey Source: https://docs.siftstack.com/api-reference/webhookservice/getwebhooksignaturekey /openapi.json get /api/v1/webhooks/signature-key Retrieve the current webhook signature key. Will return a not found error if one doesn't yet exist. # ListWebhookLogs Source: https://docs.siftstack.com/api-reference/webhookservice/listwebhooklogs /openapi.json get /api/v1/webhooks/logs Retrieve and optionally filter a list of webhook logs. # ListWebhooks Source: https://docs.siftstack.com/api-reference/webhookservice/listwebhooks /openapi.json get /api/v1/webhooks Retrieve and optionally filter a list of webhooks. # TestWebhook Source: https://docs.siftstack.com/api-reference/webhookservice/testwebhook /openapi.json post /api/v1/webhooks:test Test an existing webhook or a webhook create request. This RPC will attempt to send an actual webhook with the provided parameters and forward back the response from the target. # ToggleWebhookSignatureKeyActivation Source: https://docs.siftstack.com/api-reference/webhookservice/togglewebhooksignaturekeyactivation /openapi.json put /api/v1/webhooks/signature-key Generate a new webhook signature key and replace the previous one. The activation state of the new key will match the activation state of the previous. # ToggleWebhookSignatureKeyActivation Source: https://docs.siftstack.com/api-reference/webhookservice/togglewebhooksignaturekeyactivation-1 /openapi.json patch /api/v1/webhooks/signature-key Set the activation state of the organization's current webhook signature key. Will return a not found error if one doesn't yet exist. # UpdateWebhook Source: https://docs.siftstack.com/api-reference/webhookservice/updatewebhook /openapi.json patch /api/v1/webhooks Update select fields of an existing webhook. # Manage Run file attachments Source: https://docs.siftstack.com/api/attachments/manage-run-file-attachments Attach and remove file attachments on a Run using the API. After completing this workflow, you can attach a file to a Run, remove a file from a Run, and replace an outdated file with a new version, all using the API. ## Before you begin * You have [a Sift API key and your base URLs](/documentation/manage/set-up-api-access). * You have the ID of the Run where you want to attach or remove a file. ## How Run file attachments work [Attaching](#attach-a-file-to-a-run) a file to a Run uploads it and creates a remote file entry. [Removing](#remove-a-file-from-a-run) a file deletes that entry. To [put a new version](#update-a-run-file-attachment) of a file on a Run, remove the existing version and attach the new one. ## Attach a file to a Run `POST /api/v0/remote-files/upload` uploads a file and creates its remote file entry in a single request. This endpoint is not currently listed in the REST API reference. Call it with the file and the Run's ID. ```bash theme={null} curl --request POST \ --url "$SIFT_REST_URL/api/v0/remote-files/upload" \ --header "Authorization: Bearer $SIFT_API_KEY" \ --form "entityId=YOUR_RUN_ID" \ --form "entityType=runs" \ --form "file=@/path/to/your-file.png" ``` ## Remove a file from a Run `DeleteRemoteFile` requires the file's `remoteFileId`. 1. Look up the `remoteFileId` by calling [`ListRemoteFiles`](/api-reference/remotefileservice/listremotefiles) with a `filter` scoped to the Run. ```bash theme={null} curl --request GET \ --url "$SIFT_REST_URL/api/v1/remote-files" \ --header "Authorization: Bearer $SIFT_API_KEY" \ --get \ --data-urlencode 'filter=entity_id == "YOUR_RUN_ID"' ``` The response's `remoteFiles` array includes each file's `remoteFileId` and `fileName`. 2. Call [`DeleteRemoteFile`](/api-reference/remotefileservice/deleteremotefile) with that `remoteFileId`. ```bash theme={null} curl --request DELETE \ --url "$SIFT_REST_URL/api/v1/remote-files/YOUR_REMOTE_FILE_ID" \ --header "Authorization: Bearer $SIFT_API_KEY" ``` ## Update a Run file attachment [`UpdateRemoteFile`](/api-reference/remotefileservice/updateremotefile) only updates a file's `description` and `metadataValues`, not its contents. To put a new version of a file on a Run: 1. [Remove the outdated file](#remove-a-file-from-a-run). 2. [Attach the new file](#attach-a-file-to-a-run) to the same Run. ## Verify # Authenticate with the API Source: https://docs.siftstack.com/api/authenticate/authenticate-with-the-api Authenticate REST or gRPC requests to Sift using an API key and a base URL. Every request to the REST or gRPC API requires an API key and a base URL, both from the same provisioned environment. ## Before you begin * You have [a Sift API key and your REST and gRPC base URLs](/documentation/manage/set-up-api-access). ## Send an authenticated request Replace `$SIFT_API_KEY` and `$SIFT_REST_BASE_URL` with your actual values, then run: ```bash theme={null} curl -H "authorization: Bearer $SIFT_API_KEY" $SIFT_REST_BASE_URL/api/v1/ping ``` Replace `$SIFT_API_KEY`, `$SIFT_GRPC_BASE_URL`, and `$PORT_NUM` with your actual values, then run: ```bash theme={null} grpcurl -H "authorization: Bearer $SIFT_API_KEY" $SIFT_GRPC_BASE_URL:$PORT_NUM sift.ping.v1.PingService/Ping ``` **Base URL format:** Do not include `https://` in the base URL, use only the hostname. `$PORT_NUM` is always `443`. Ready to build a real integration? See [Connect with an official client](/api/reference/protocol-buffers/index#connect-with-an-official-client) to use an official Python, Rust, or Go client. **Rate limits:** Sift enforces [rate limits](/documentation/manage/set-up-api-access#api-rate-limits) per organization and per endpoint, for both REST and gRPC. # Generate a gRPC client with Buf Source: https://docs.siftstack.com/api/clients/generate-a-client-with-buf Compile Sift's Protocol Buffers into a client for your language and protobuf version when an official client doesn't fit your environment. After completing this workflow, you can generate a gRPC client for your language and protobuf version, using [Buf](https://buf.build/docs/cli/) to compile Sift's Protocol Buffers. This workflow can help if, for example: * Your language isn't Python, Rust, or Go, the languages Sift's official clients support. * Your environment requires a different protobuf version than Sift's packaged client uses, for example because your firmware or software is pinned to an older version. * You need raw generated stubs for a custom ingestion pipeline instead of a full SDK. ## Before you begin * Install the [Buf CLI](https://buf.build/docs/installation/). * Have access to clone the [Sift GitHub repository](https://github.com/sift-stack/sift). * Identify the Buf plugin for your target language. This guide uses Python as an example, but the process applies to any language Buf supports. ## How Buf-based client generation works Buf compiles Sift's Protocol Buffers into client code using plugins you specify in a configuration file. Each plugin targets a language and can be pinned to a specific version, independent of the protobuf version used inside Sift's own client libraries. This is what makes Buf useful when the official client doesn't fit: you control the exact language, protobuf version, and generated output, rather than taking Sift's packaged SDK as-is. ## Generate a client with Buf 1. Create a new directory for your client, and navigate into it. This directory holds your Buf configuration and the generated code. ```bash theme={null} mkdir sift-grpc-python-client cd sift-grpc-python-client ``` 2. Authenticate to the Buf Schema Registry. The plugins in this workflow run remotely on Buf's registry, so an unauthenticated CLI will fail with an invalid token error. ```bash theme={null} buf registry login ``` 3. Clone the [Sift GitHub repository](https://github.com/sift-stack/sift) to access the Protocol Buffer definitions locally. ```bash theme={null} git clone https://github.com/sift-stack/sift.git ``` **Location:** The `.proto` files are located in the [sift subdirectory](https://github.com/sift-stack/sift/tree/main/protos/sift) inside `protos/` in the repository. 4. In your client directory, create a file named `buf.gen.yaml`. This file specifies the plugins Buf should use, the versions to pin, and where the generated code should be written. ```bash theme={null} nano buf.gen.yaml ``` ```yaml theme={null} version: v1 managed: enabled: true plugins: - plugin: buf.build/grpc/python:v1.62.1 out: gen - plugin: buf.build/protocolbuffers/python out: gen - plugin: buf.build/protocolbuffers/pyi:v26.1 out: gen ``` This configuration generates Python message classes, gRPC client and server stubs, and type hint files to the `gen/` directory. **Version pinning:** To match a protobuf version required by your environment, pin the plugin version, for example `buf.build/protocolbuffers/python:v3.19.5`. **Other languages:** To generate a client for another language, use a different plugin here. Only the plugin selection and version pinning change; the rest of this workflow stays the same. 5. From inside your client directory, export the `.proto` files from the Sift repository into a local directory. `sift_protos` is the output directory in this example, and `sift/protos/buf.yaml` is the [`buf.yaml`](https://github.com/sift-stack/sift/blob/main/protos/buf.yaml) file in the protos subdirectory of the cloned repository. ```bash theme={null} buf export sift/protos --output=sift_protos --config sift/protos/buf.yaml ``` 6. In the directory containing `buf.gen.yaml`, generate the client code from the exported `.proto` files. ```bash theme={null} buf generate sift_protos ``` **Dependencies:** Generated code often requires additional runtime dependencies to work. Check the documentation for each plugin you use to identify what to install. ## Verify the generated client Check the output directories specified in `buf.gen.yaml`. For the example configuration above, the `gen/` directory should contain: * Python message classes * gRPC client and server stubs * `.pyi` type hint files If any of these are missing, confirm the corresponding plugin is listed in `buf.gen.yaml` and that `buf generate` completed without errors. # Export data programmatically Source: https://docs.siftstack.com/api/export/export-data-programmatically Export telemetry data from Sift using the REST API, an official client library, or a client generated with Buf. After completing this workflow, you can export Channel data from any Run into the tool or pipeline your team uses for analysis. Sift's REST API and client libraries let you export telemetry data from Runs programmatically for use in external tools, custom pipelines, and downstream analysis environments such as MATLAB or Python. ## Before you export * You have [a Sift API key and your base URLs](/documentation/manage/set-up-api-access). * Ensure the API key you use to export data, including to query data, is [created in the environment](/documentation/manage/set-up-api-access#use-api-keys-across-multiple-environments) that contains the data. * You have the ID of the Run and the IDs of the Channels you want to export. One option is to find these in the Sift UI or by querying the [`ListRuns`](/api-reference/runservice/listruns) and [`ListChannels`](/api-reference/channelservice/listchannels) endpoints. ## How does programmatic export work Sift provides two programmatic export methods, **data querying** and **export data to file**, each available through the REST API and official client libraries (Python, Rust, and Go). Clients for other languages can be generated using [Buf](/api/clients/generate-a-client-with-buf). ## Query Channel data ### Use the REST API To query Channel data, call the [`GetData`](/api-reference/dataservice/getdata-1) endpoint. 1. Query Channel data ```bash theme={null} curl --request POST \ --url "https://api.siftstack.com/api/v2/data" \ --header "Authorization: Bearer $SIFT_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "queries": [ { "channel": { "channelId": "YOUR_CHANNEL_ID_1", "runId": "YOUR_RUN_ID" } }, { "channel": { "channelId": "YOUR_CHANNEL_ID_2", "runId": "YOUR_RUN_ID" } } ], "startTime": "2026-03-13T19:43:25.557Z", "endTime": "2026-03-13T19:48:25.557Z", "sampleMs": 0, "pageSize": 100000, "pageToken": "" }' ``` **endTime**: This field is exclusive, so a sample that falls exactly at or after `endTime` is not included in the response. If a value you expect to see is missing, try extending `endTime` slightly past the boundary you actually want. **sampleMs**: Set `sampleMs` to `0`, or omit it, to return the full, unsampled dataset, recommended for external data analysis. Any other value downsamples the response using LTTB, a shape-preserving algorithm intended for plotting rather than analysis; it returns approximately one representative point per that many milliseconds rather than sampling at a literal fixed interval. **Timeseries Panel**: The Sift app's Timeseries Panel offers a choice of sampling methods (LTTB, Min/Max, and Changed Only), but [`GetData`](/api-reference/dataservice/getdata-1) only supports LTTB; the other methods are not currently available through this endpoint. 2. Paginate if needed If the response includes a non-empty `nextPageToken`, resend the same request with `pageToken` set to that value to retrieve the next batch. Repeat until `nextPageToken` comes back empty. ```bash theme={null} curl --request POST \ --url "https://api.siftstack.com/api/v2/data" \ --header "Authorization: Bearer $SIFT_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "queries": [ { "channel": { "channelId": "YOUR_CHANNEL_ID_1", "runId": "YOUR_RUN_ID" } } ], "startTime": "2026-03-13T19:43:25.557Z", "endTime": "2026-03-13T19:48:25.557Z", "sampleMs": 0, "pageSize": 100000, "pageToken": "TOKEN_FROM_PREVIOUS_RESPONSE" }' ``` ### Use the Python client The [official Python client](https://pypi.org/project/sift-stack-py/) provides two methods for querying Channel data: * [client.channels.get\_data\_as\_arrow()](https://sift-stack.github.io/sift/python/latest/reference/sift_client/resources/#sift_client.resources.ChannelsAPI.get_data_as_arrow) returns an Apache Arrow table. Recommended when converting data for use in other tools. * [client.channels.get\_data()](https://sift-stack.github.io/sift/python/latest/reference/sift_client/resources/#sift_client.resources.ChannelsAPI.get_data) returns typed Python value objects. 1. Initialize the client ```python theme={null} import os from datetime import datetime, timezone from dotenv import load_dotenv from sift_client import SiftClient load_dotenv() client = SiftClient( api_key=os.getenv("SIFT_API_KEY"), grpc_url=os.getenv("SIFT_GRPC_URI"), rest_url=os.getenv("SIFT_REST_URI"), ) ``` 2. Retrieve the data Fetch the Channel object using its ID, then call [client.channels.get\_data\_as\_arrow()](https://sift-stack.github.io/sift/python/latest/reference/sift_client/resources/#sift_client.resources.ChannelsAPI.get_data_as_arrow). The method returns a `dict` where each key is a Channel name and the value is an Apache Arrow table. ```python theme={null} channel = client.channels.get(channel_id="YOUR_CHANNEL_ID") result = client.channels.get_data_as_arrow( channels=[channel], run="YOUR_RUN_ID", start_time=datetime(YYYY, MM, DD, HH, MM, SS, microsecond, tzinfo=timezone.utc), # e.g. datetime(2026, 4, 15, 0, 17, 49, 984000, tzinfo=timezone.utc) = 2026-04-15T00:17:49.984Z end_time=datetime(YYYY, MM, DD, HH, MM, SS, microsecond, tzinfo=timezone.utc), # e.g. datetime(2026, 4, 15, 0, 18, 26, 609000, tzinfo=timezone.utc) = 2026-04-15T00:18:26.609Z ) # Access the table by Channel name and convert to a pandas DataFrame df = result["YOUR_CHANNEL_NAME"].to_pandas() ``` Or using [client.channels.get\_data()](https://sift-stack.github.io/sift/python/latest/reference/sift_client/resources/#sift_client.resources.ChannelsAPI.get_data), which returns a `dict[str, pd.DataFrame]` directly with no conversion needed: ```python theme={null} result = client.channels.get_data( channels=[channel], run="YOUR_RUN_ID", start_time=datetime(YYYY, MM, DD, HH, MM, SS, microsecond, tzinfo=timezone.utc), # e.g. datetime(2026, 4, 15, 0, 17, 49, 984000, tzinfo=timezone.utc) = 2026-04-15T00:17:49.984Z end_time=datetime(YYYY, MM, DD, HH, MM, SS, microsecond, tzinfo=timezone.utc), # e.g. datetime(2026, 4, 15, 0, 18, 26, 609000, tzinfo=timezone.utc) = 2026-04-15T00:18:26.609Z ) # Access the DataFrame by Channel name df = result["YOUR_CHANNEL_NAME"] ``` ## Export data to file ### Use the REST API To export data to a file, call the [`ExportData`](/api-reference/exportservice/exportdata) and [`GetDownloadUrl`](/api-reference/exportservice/getdownloadurl) endpoints. 1. Submit the export job ```bash theme={null} curl --request POST \ --url "https://api.siftstack.com/api/v1/export" \ --header "Authorization: Bearer $SIFT_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "runsAndTimeRange": { "runIds": ["YOUR_RUN_ID"] }, "channelIds": ["CHANNEL_ID_1", "CHANNEL_ID_2"], "outputFormat": "EXPORT_OUTPUT_FORMAT_PARQUET" }' ``` **outputFormat**: This is a fixed value to select, not a placeholder to replace with your own text. 2. Retrieve the download link If the response includes a `presignedUrl`, the export completed immediately and the file is ready to download. If the response includes a `jobId` instead, poll this endpoint until `presignedUrl` is populated: ```bash theme={null} curl --request GET \ --url "https://api.siftstack.com/api/v1/export/YOUR_JOB_ID/download-url" \ --header "Authorization: Bearer $SIFT_API_KEY" ``` ### Use the Python client The [official Python client](https://sift-stack.github.io/sift/python/latest/#installation) provides two methods for exporting data to file: * [client.data\_export.export()](https://sift-stack.github.io/sift/python/latest/reference/sift_client/resources/#sift_client.resources.DataExportAPI.export) submits the export job. * [job.wait\_and\_download()](https://sift-stack.github.io/sift/python/latest/reference/sift_client/sift_types/job/#sift_client.sift_types.job.Job.wait_and_download) polls until complete, downloads, and extracts the result automatically. Returns a list of `Path` objects pointing to the extracted files. 1. Initialize the client ```python theme={null} import os from dotenv import load_dotenv from sift_client import SiftClient from sift_client.sift_types.export import ExportOutputFormat load_dotenv() client = SiftClient( api_key=os.getenv("SIFT_API_KEY"), grpc_url=os.getenv("SIFT_GRPC_URI"), rest_url=os.getenv("SIFT_REST_URI"), ) ``` 2. Submit the export job and download the result ```python theme={null} job = client.data_export.export( output_format=ExportOutputFormat.PARQUET, runs=["YOUR_RUN_ID"], channels=["YOUR_CHANNEL_ID_1", "YOUR_CHANNEL_ID_2"], ) paths = job.wait_and_download(output_dir=".") # downloads and extracts to the directory where the script is run ``` # Export data to MATLAB Source: https://docs.siftstack.com/api/export/export-data-to-matlab Get telemetry data from Sift into MATLAB for analysis using the official Python client or the REST API. After completing this workflow, you can bring Channel data from Sift into MATLAB and load it into a timetable or table ready for analysis. After data is stored in Sift, it can be exported into MATLAB for analysis. Sift recommends using the official Python [client](https://pypi.org/project/sift-stack-py/) via MATLAB's built-in Python interface. If your team cannot use Python, the REST API is also supported natively from MATLAB. ## Before you begin * You have [a Sift API key and your base URLs](/documentation/manage/set-up-api-access). * Ensure the API key you use to export data, including to query data, is [created in the environment](/documentation/manage/set-up-api-access#use-api-keys-across-multiple-environments) that contains the data. * You have the ID of the Run and the IDs of the Channels you want to export. One option is to find these in the Sift UI or by querying the [`ListRuns`](/api-reference/runservice/listruns) and [`ListChannels`](/api-reference/channelservice/listchannels) endpoints. ## How exporting to MATLAB works Sift provides two programmatic export methods: **data querying**, which returns Channel data immediately in the response, and **export data to file**, which processes the export in the background and produces a downloadable file. Both methods are available through either the **Python client** or the **REST API**, the two options for importing data into MATLAB. ## Use the Python client via MATLAB's Python interface ### Set up the Python environment The Python client requires Python 3.8 or later installed on the same machine as MATLAB. Both methods below rely on the Sift Python client running inside a Python virtual environment that MATLAB can access. Complete the following steps once before running either method. This sets up the Python environment, points MATLAB to it, and stores your Sift credentials. 1. Create a virtual environment ```bash theme={null} python3 -m venv env source env/bin/activate ``` 2. Install the required packages Create a file named `requirements.txt` in your working directory with the following contents: ``` sift-stack-py==0.18.0 pyarrow==21.0.0 ``` **Versions**: `sift-stack-py` 0.18.0 is the latest release as of this guide's last update. If a newer version is available by the time you're reading this, it likely works as well, but hasn't been verified against this guide. Creating a `requirements.txt` file as shown above, rather than installing packages individually, is recommended to avoid version mismatches as new releases of `sift-stack-py` become available. With the virtual environment active, install from the file: ```bash theme={null} pip install -r requirements.txt ``` 3. Point MATLAB to your virtual environment In the MATLAB Command Window, run: ```matlab theme={null} pyenv(Version="/path/to/env/bin/python") ``` Replace `/path/to/env` with the full path to the virtual environment you created. To find it, run `which python` in your terminal while the virtual environment is active. 4. Verify your Python environment In MATLAB, confirm that the correct Python environment is being used: ```matlab theme={null} pyenv ``` If the wrong environment is selected, point MATLAB at the correct one: ```matlab theme={null} pyenv(Version="/path/to/your/python") ``` 5. Set your Sift credentials Replace the placeholder values below with your actual credentials, then run the following in the MATLAB Command Window. This creates a `.env` file in your current working directory. ```matlab theme={null} lines = [ "SIFT_API_KEY=your-api-key-here" "SIFT_GRPC_URI=your-grpc-url-here" "SIFT_REST_URI=your-rest-url-here" ]; writelines(lines, '.env') ``` To confirm where the file was saved, run `pwd`. Then load the credentials: ```matlab theme={null} loadenv('.env') disp(getenv('SIFT_API_KEY')) % confirms the key was loaded ``` ### Query Channel data 1. Initialize the client Run the following in the MATLAB Command Window to connect to Sift: ```matlab theme={null} sift_mod = py.importlib.import_module('sift_client'); client = sift_mod.SiftClient(pyargs( ... 'api_key', getenv('SIFT_API_KEY'), ... 'grpc_url', getenv('SIFT_GRPC_URI'), ... 'rest_url', getenv('SIFT_REST_URI'))); disp(client) % confirms the client connected ``` 2. List Channels and query data Use [client.runs.find](https://sift-stack.github.io/sift/python/latest/reference/sift_client/resources/#sift_client.resources.RunsAPI.find) to find a single Run by name, or [client.runs.list\_](https://sift-stack.github.io/sift/python/latest/reference/sift_client/resources/#sift_client.resources.RunsAPI.list_) to search across multiple Runs. When a Run is provided to [client.channels.get\_data\_as\_arrow](https://sift-stack.github.io/sift/python/latest/reference/sift_client/resources/#sift_client.resources.ChannelsAPI.get_data_as_arrow), the Run's time range is used automatically so `start_time` and `end_time` are not needed. Find the Run. Use Approach 1 to find a single Run by name: ```matlab theme={null} run = client.runs.find(pyargs('name', 'YOUR_RUN_NAME')); disp(run) % shows the Run name, ID and time range ``` Use Approach 2 to search across multiple Runs: ```matlab theme={null} runs = client.runs.list_(pyargs('name', 'YOUR_RUN_NAME')); run = runs{1}; disp(run) % shows the Run name, ID and time range ``` Find Channels scoped to the Run using [client.channels.list\_](https://sift-stack.github.io/sift/python/latest/reference/sift_client/resources/#sift_client.resources.ChannelsAPI.list_): ```matlab theme={null} channels = client.channels.list_(pyargs( ... 'run', run, ... 'name', 'YOUR_CHANNEL_NAME')); disp(channels) % shows the Channel objects found ``` If you already know the Channel ID, you can use [client.channels.get](https://sift-stack.github.io/sift/python/latest/reference/sift_client/resources/#sift_client.resources.ChannelsAPI.get) instead: ```matlab theme={null} channel = client.channels.get(pyargs('channel_id', 'YOUR_CHANNEL_ID')); channels = py.list({channel}); disp(channels) % confirms the Channel was found ``` Query data for the full Run: ```matlab theme={null} arrow_result = client.channels.get_data_as_arrow(pyargs( ... 'channels', channels, ... 'run', run)); disp(arrow_result) % shows the Python dict with Channel names and Arrow tables ``` To query a specific time window within the Run, pass `start_time` and `end_time`: ```matlab theme={null} utc = py.datetime.timezone(py.datetime.timedelta(0)); start_dt = py.datetime.datetime(int32(YYYY), int32(MM), int32(DD), int32(HH), int32(MM), int32(SS), pyargs('tzinfo', utc)); % e.g. int32(2026), int32(4), int32(15), int32(0), int32(17), int32(49) end_dt = py.datetime.datetime(int32(YYYY), int32(MM), int32(DD), int32(HH), int32(MM), int32(SS), pyargs('tzinfo', utc)); % e.g. int32(2026), int32(4), int32(15), int32(0), int32(18), int32(26) arrow_result = client.channels.get_data_as_arrow(pyargs( ... 'channels', channels, ... 'run', run, ... 'start_time', start_dt, ... 'end_time', end_dt)); disp(arrow_result) % shows the Python dict with Channel names and Arrow tables ``` `arrow_result` is a Python dict where each key is a Channel name and the value is an Apache Arrow table. 3. Write to Parquet and load into MATLAB Data returned by [get\_data\_as\_arrow](https://sift-stack.github.io/sift/python/latest/reference/sift_client/resources/#sift_client.resources.ChannelsAPI.get_data_as_arrow) comes back as a Python object that MATLAB cannot consume directly. Writing it to a Parquet file and loading it with `parquetread` converts it into a format MATLAB understands. Replace `YOUR_CHANNEL_NAME` with the exact name of your Channel as it appears in Sift, for example `temperature`. ```matlab theme={null} pq = py.importlib.import_module('pyarrow.parquet'); pq.write_table(arrow_result{'YOUR_CHANNEL_NAME'}, 'sift_export.parquet'); tt = parquetread('sift_export.parquet', ... 'OutputType', 'timetable', ... 'RowTimes', 'x__index_level_0__'); % Rename the time dimension to something readable tt.Properties.DimensionNames{1} = 'time'; disp(tt) ``` The output will look similar to this: ``` time temperature ____________________ ___________ 15-Apr-2026 00:17:49 25.152 15-Apr-2026 00:17:50 29.854 15-Apr-2026 00:17:50 28.995 15-Apr-2026 00:17:51 31.947 15-Apr-2026 00:17:51 23.975 ``` You will see a warning about table variable names being modified. This is expected. MATLAB automatically renames the internal timestamp column from `__index_level_0__` to `x__index_level_0__` to comply with MATLAB identifier rules. The timetable is created correctly and the warning can be safely ignored. ### Export data to file 1. Submit the export job Submit the job using [client.data\_export.export](https://sift-stack.github.io/sift/python/latest/reference/sift_client/resources/#sift_client.resources.DataExportAPI.export). See the [`ExportOutputFormat`](https://sift-stack.github.io/sift/python/latest/reference/sift_client/sift_types/export/#sift_client.sift_types.export.ExportOutputFormat) reference for the accepted output format values. ```matlab theme={null} export_mod = py.importlib.import_module('sift_client.sift_types.export'); ExportOutputFormat = export_mod.ExportOutputFormat; job = client.data_export.export(pyargs( ... 'output_format', ExportOutputFormat.CSV, ... 'runs', py.list({'YOUR_RUN_ID'}), ... 'channels', py.list({'YOUR_CHANNEL_ID'}))); % Extract the job ID from the Python job object jobId = char(job.id_); disp(jobId) % confirms the job was submitted ``` 2. Wait for the job and download the result Use `client.jobs.wait_and_download` with `show_progress` set to `false` to avoid the progress bar conflict with MATLAB's Command Window: ```matlab theme={null} client.jobs.wait_and_download(pyargs( ... 'job', job, ... 'show_progress', false, ... 'output_dir', '.')); ``` 3. Load the result into MATLAB The exported file is saved to MATLAB's current working directory. Run `dir` to find the filename: ```matlab theme={null} dir('*.csv') ``` Then load it: ```matlab theme={null} T = readtable('YOUR_FILENAME.csv', ... 'Delimiter', ',', ... 'VariableNamingRule', 'preserve'); disp(T) ``` The column names include the full Run and Asset path, for example `runName|assetName|temperature`. To rename a column after loading: ```matlab theme={null} T.Properties.VariableNames{2} = 'temperature'; ``` ## Use the REST API via webread ### Query Channel data 1. Set your Sift credentials Replace the placeholder values below with your actual credentials, then run the following in the MATLAB Command Window. This creates a `.env` file in your current working directory. ```matlab theme={null} lines = [ "SIFT_API_KEY=your-api-key-here" "SIFT_REST_URI=your-rest-url-here" ]; writelines(lines, '.env') ``` To confirm where the file was saved, run `pwd`. Then load the credentials: ```matlab theme={null} loadenv('.env') ``` 2. Query Channel data To query Channel data, call the [`GetData`](/api-reference/dataservice/getdata-1) endpoint. ```matlab theme={null} opts = weboptions( ... 'RequestMethod', 'post', ... 'MediaType', 'application/json', ... 'ContentType', 'json', ... 'HeaderFields', {'Authorization', ['Bearer ' getenv('SIFT_API_KEY')]}); query = struct( ... 'queries', {{struct('channel', struct( ... 'channelId', 'YOUR_CHANNEL_ID', ... 'runId', 'YOUR_RUN_ID'))}}, ... 'startTime', 'YYYY-MM-DDTHH:MM:SS.sssZ', ... % e.g. 2026-04-15T00:17:49.984Z 'endTime', 'YYYY-MM-DDTHH:MM:SS.sssZ', ... % e.g. 2026-04-15T00:18:26.609Z 'sampleMs', 0, ... % 0 returns full-fidelity data; omit or set to 0 for analysis 'pageSize', 100000, ... 'pageToken', ''); allResults = {}; while true result = webwrite([getenv('SIFT_REST_URI') '/api/v2/data'], query, opts); allResults{end+1} = result; %#ok if isempty(result.nextPageToken) break end query.pageToken = result.nextPageToken; end disp(allResults) % each cell holds one page of the raw API response ``` **endTime**: This field is exclusive, so a sample that falls exactly at or after `endTime` is not included in the response. If a value you expect to see is missing, or the last row in MATLAB doesn't match what the Sift app shows for the same time range, try extending `endTime` slightly past the boundary you actually want. **sampleMs**: Set `sampleMs` to `0`, or omit it, to return the full, unsampled dataset, recommended for external data analysis. Any other value downsamples the response using LTTB, a shape-preserving algorithm intended for plotting rather than analysis; it returns approximately one representative point per that many milliseconds rather than sampling at a literal fixed interval. **Timeseries Panel**: The Sift app's Timeseries Panel offers a choice of sampling methods (LTTB, Min/Max, and Changed Only), but [`GetData`](/api-reference/dataservice/getdata-1) only supports LTTB; the other methods are not currently available through this endpoint. **Pagination**: `GetData` returns at most `pageSize` values per request; see the [`pageSize`](/api-reference/dataservice/getdata-1#body-page-size) reference for the exact limits and how they're applied. If more data exists beyond the returned page, the response's `nextPageToken` field is non-empty and the result is truncated, not an error. Client libraries such as `sift-stack-py` handle this pagination internally, but MATLAB's `webwrite` does not, so a manual REST call must loop on `pageToken` itself to retrieve the full dataset, as shown above. The loop continues sending the same query with an updated `pageToken` until `nextPageToken` comes back empty, which signals that all data has been retrieved. Skipping this loop, as in a single `webwrite` call, silently returns only the first page even when more data exists. 3. Query multiple Channels To query more than one Channel in a single request, add a `struct` to the `queries` cell array for each Channel. The nested structure can be difficult to get right by hand, so it helps to build the `struct` in MATLAB first, then use `jsonencode` to inspect the exact JSON it produces before sending it. ```matlab theme={null} query = struct( ... 'queries', {{ ... struct('channel', struct('channelId', 'YOUR_CHANNEL_ID_1', 'runId', 'YOUR_RUN_ID')), ... struct('channel', struct('channelId', 'YOUR_CHANNEL_ID_2', 'runId', 'YOUR_RUN_ID')), ... struct('channel', struct('channelId', 'YOUR_CHANNEL_ID_3', 'runId', 'YOUR_RUN_ID')) ... }}, ... 'startTime', 'YYYY-MM-DDTHH:MM:SS.sssZ', ... % e.g. 2026-04-15T00:17:49.984Z 'endTime', 'YYYY-MM-DDTHH:MM:SS.sssZ', ... % e.g. 2026-04-15T00:18:26.609Z 'sampleMs', 0, ... % 0 returns full-fidelity data; omit or set to 0 for analysis 'pageSize', 100000, ... 'pageToken', ''); ``` Write the `struct` to a JSON file to confirm the nesting is correct before submitting it: ```matlab theme={null} jsonStr = jsonencode(query, 'PrettyPrint', true); fid = fopen('query.json', 'w'); fprintf(fid, '%s', jsonStr); fclose(fid); disp(jsonStr) % shows the JSON that will be sent ``` If you build or edit the JSON file directly instead of constructing the `struct` in MATLAB, load it back in with `jsondecode` before submitting: ```matlab theme={null} query = jsondecode(fileread('query.json')); ``` Submit the request. `webwrite` accepts the `struct` directly and encodes it to JSON internally, so the same `query` variable used to inspect the file can be sent as is. A multichannel request is subject to the same `pageSize` limit as a single-Channel request, so this uses the same `pageToken` loop shown in the previous step: ```matlab theme={null} allResults = {}; while true result = webwrite([getenv('SIFT_REST_URI') '/api/v2/data'], query, opts); allResults{end+1} = result; %#ok if isempty(result.nextPageToken) break end query.pageToken = result.nextPageToken; end disp(allResults) % each cell holds one page of the raw API response, with data for all requested Channels ``` 4. Load into a MATLAB timetable Each page in `allResults` can contain data for more than one Channel. Group the values by Channel name across all pages, then build one timetable per Channel: ```matlab theme={null} channelData = struct(); for i = 1:numel(allResults) for j = 1:numel(allResults{i}.data) channelName = matlab.lang.makeValidName(allResults{i}.data(j).metadata.channel.name); if ~isfield(channelData, channelName) channelData.(channelName) = []; end channelData.(channelName) = [channelData.(channelName); allResults{i}.data(j).values]; end end channelNames = fieldnames(channelData); timetables = struct(); for k = 1:numel(channelNames) name = channelNames{k}; dt = struct2table(channelData.(name)); dt.time = datetime(dt.timestamp, ... 'InputFormat', 'uuuu-MM-dd''T''HH:mm:ss.SSS''Z''', ... 'TimeZone', 'utc'); dt.timestamp = []; timetables.(name) = table2timetable(dt, 'RowTimes', 'time'); end disp(timetables) % struct with one timetable per Channel, e.g. timetables.ADCS_RW_Speed_Y ``` `matlab.lang.makeValidName` converts Channel names such as `ADCS.RW_Speed_Y` into valid MATLAB field names (`ADCS_RW_Speed_Y`), since field names can't contain periods. This same code works whether `allResults` came from a single-Channel or multichannel query, since it groups by however many Channels are actually present in the response. ### Export data to file 1. Submit the export job To export data to a file, call the [`ExportData`](/api-reference/exportservice/exportdata) and [`GetDownloadUrl`](/api-reference/exportservice/getdownloadurl) endpoints. ```matlab theme={null} opts = weboptions( ... 'RequestMethod', 'post', ... 'MediaType', 'application/json', ... 'ContentType', 'json', ... 'HeaderFields', {'Authorization', ['Bearer ' getenv('SIFT_API_KEY')]}); exportBody = struct( ... 'runsAndTimeRange', struct('runIds', {{'YOUR_RUN_ID'}}), ... 'channelIds', {{'YOUR_CHANNEL_ID'}}, ... 'outputFormat', 'EXPORT_OUTPUT_FORMAT_CSV'); exportResult = webwrite([getenv('SIFT_REST_URI') '/api/v1/export'], exportBody, opts); disp(exportResult) % shows the job ID and status ``` **outputFormat**: `EXPORT_OUTPUT_FORMAT_CSV` is an actual value that needs to be passed as-is, not a placeholder to replace with your own text. 2. Retrieve the download link ```matlab theme={null} if ~isempty(exportResult.presignedUrl) websave('sift_export.zip', exportResult.presignedUrl); else getOpts = weboptions( ... 'HeaderFields', {'Authorization', ['Bearer ' getenv('SIFT_API_KEY')]}, ... 'ContentType', 'json'); jobId = exportResult.jobId; presignedUrl = ''; while isempty(presignedUrl) pause(5); urlResult = webread([getenv('SIFT_REST_URI') '/api/v1/export/' jobId '/download-url'], getOpts); presignedUrl = string(urlResult.presignedUrl); end websave('sift_export.zip', presignedUrl); end ``` 3. Unzip and load into MATLAB ```matlab theme={null} unzip('sift_export.zip', 'sift_export'); ``` The ZIP contains a file with a name generated by Sift. The format matches the `outputFormat` you specified when submitting the job, for example `sift_data_export_2026-05-19_172841.csv` for CSV. Run the following to see the exact filename: ```matlab theme={null} dir('sift_export') ``` Then load it using the actual filename: ```matlab theme={null} T = readtable('sift_export/YOUR_FILENAME.csv', ... 'Delimiter', ',', ... 'VariableNamingRule', 'preserve'); disp(T) ``` The column names include the full Run and Asset path, for example `runName|assetName|temperature`. To rename a column after loading: ```matlab theme={null} T.Properties.VariableNames{2} = 'temperature'; disp(T) ``` ## Reference * [Export data programmatically](/api/export/export-data-programmatically) # API Source: https://docs.siftstack.com/api/overview Automate telemetry review and data export using Sift's REST and gRPC APIs Every request needs an API key and a base URL, both obtained in the Sift UI, to authenticate REST or gRPC requests. Create an API key and find your REST and gRPC base URLs. Send an authenticated request to the REST or gRPC API. Evaluate Rules programmatically to generate Reports and Annotations, including Rules created and evaluated entirely through the API. Create, preview, and evaluate Rules programmatically against a Run or Asset to generate a Report and Annotations. Create, preview, and evaluate Ad Hoc Rules programmatically for automated pipelines such as CI/CD.. Pull Channel data out of Sift for use in external tools, custom pipelines, and analysis environments. Query Channel data or export it to file using the REST API or official client libraries. Get telemetry from Sift into MATLAB using the Python client or the REST API. ## Choosing between REST and gRPC Sift exposes two APIs, REST and [gRPC](/api/reference/protocol-buffers/index), both generated from the same underlying Protocol Buffers definitions to ensure consistency. **No code required:** For command-line imports and exports, use the [Sift CLI](/documentation/cli/sift-cli) instead of calling the API directly. # action_type Source: https://docs.siftstack.com/api/reference/protocol-buffers/action_type sift/common/v1/action_type.proto ## Services *RPC methods exposed by this API.* ## Messages *Data models used across requests/responses.* ## Enums *Allowed constant values used in message fields.* ### ActionType ActionType represents the type of action being performed on a resource Granular ABAC actions, broken up by CRUD. | Name | Number | Description | | :--------------------------- | :----- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ACTION\_TYPE\_UNSPECIFIED | 0 | | | ACTION\_TYPE\_INGEST\_DATA | 110 | Create actions (reserving 100 for generic create) | | ACTION\_TYPE\_CREATE\_RUN | 120 | | | ACTION\_TYPE\_VIEW\_DETAILS | 200 | Read actions Lowest-level read action type. If this is denied, all other read actions should be denied. Used for view/search/index metadata and overview details pages. | | ACTION\_TYPE\_VIEW\_DATA | 205 | Read telemetry data values from channels/runs/assets. Keep ACTION\_TYPE\_VIEW\_DETAILS for non-telemetry "view details" style access. | | ACTION\_TYPE\_EXPORT | 210 | | | ACTION\_TYPE\_EDIT\_DETAILS | 310 | Update/Edit actions (reserving 300 for generic edit) Name, Description, Units | | ACTION\_TYPE\_EDIT\_TAGS | 312 | | | ACTION\_TYPE\_EDIT\_METADATA | 313 | | | ACTION\_TYPE\_ARCHIVE | 400 | Delete actions | # annotation_logs Source: https://docs.siftstack.com/api/reference/protocol-buffers/annotation_logs sift/annotation_logs/v1/annotation_logs.proto ## Services *RPC methods exposed by this API.* ### AnnotationLogService | Method | Request | Response | Description | | :------------------ | :-------------------------------------------------------- | :---------------------------------------------------------- | :-------------------------------------------------- | | CreateAnnotationLog | [CreateAnnotationLogRequest](#createannotationlogrequest) | [CreateAnnotationLogResponse](#createannotationlogresponse) | Creates an annotation log on an annotation. | | ListAnnotationLogs | [ListAnnotationLogsRequest](#listannotationlogsrequest) | [ListAnnotationLogsResponse](#listannotationlogsresponse) | Retrieves annotation logs using an optional filter. | | DeleteAnnotationLog | [DeleteAnnotationLogRequest](#deleteannotationlogrequest) | [DeleteAnnotationLogResponse](#deleteannotationlogresponse) | Deletes an annotation log. | ## Messages *Data models used across requests/responses.* ### AnnotationCommentBodyElement | Field | Type | Label | Description | | :------------ | :-------------------------------------------------------------------- | :---- | :---------- | | type | [AnnotationCommentBodyElementType](#annotationcommentbodyelementtype) | | | | text | string | | | | user\_mention | [AnnotationCommentUserMention](#annotationcommentusermention) | | | ### AnnotationCommentUserMention | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------- | | user\_id | string | | | | user\_email | string | | | ### AnnotationLogAssignedProperties | Field | Type | Label | Description | | :------------------------ | :----- | :---- | :---------- | | assigned\_to\_user\_id | string | | | | assigned\_to\_user\_email | string | | | ### AnnotationLogCommentProperties | Field | Type | Label | Description | | :---- | :------------------------------------------------------------ | :------- | :---------- | | body | [AnnotationCommentBodyElement](#annotationcommentbodyelement) | repeated | | ### AnnotationLogSearchResult | Field | Type | Label | Description | | :------------------------------ | :------------------------------------------------------------------------ | :---- | :---------- | | annotation\_log\_id | string | | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | annotation\_id | string | | | | kind | [AnnotationLogKind](#annotationlogkind) | | | | created\_by\_user\_id | string | | | | created\_by\_user\_name | string | | | | oneof properties. assigned | [AnnotationLogAssignedProperties](#annotationlogassignedproperties) | | | | oneof properties. state\_update | [AnnotationLogStateUpdateProperties](#annotationlogstateupdateproperties) | | | | oneof properties. comment | [AnnotationLogCommentProperties](#annotationlogcommentproperties) | | | ### AnnotationLogStateUpdateProperties | Field | Type | Label | Description | | :---- | :---------------------------------------- | :---- | :---------- | | state | [AnnotationLogState](#annotationlogstate) | | | ### CreateAnnotationLogRequest The request for a call to `AnnotationLogService_CreateAnnotationLog` to create an annotation log. | Field | Type | Label | Description | | :------------------------------ | :------------------------------------------------------------------------ | :---- | :----------------------------------------------------------------------------------- | | annotation\_id | string | | The ID of the parent annotation associated to associate with the new annotation log. | | kind | [AnnotationLogKind](#annotationlogkind) | | The kind of annotation log to create. | | oneof properties. assigned | [AnnotationLogAssignedProperties](#annotationlogassignedproperties) | | | | oneof properties. state\_update | [AnnotationLogStateUpdateProperties](#annotationlogstateupdateproperties) | | | | oneof properties. comment | [AnnotationLogCommentProperties](#annotationlogcommentproperties) | | | ### CreateAnnotationLogResponse The response of a call to `AnnotationLogService_CreateAnnotationLog`. | Field | Type | Label | Description | | :-------------- | :------------------------------------------------------ | :---- | :---------- | | annotation\_log | [AnnotationLogSearchResult](#annotationlogsearchresult) | | | ### DeleteAnnotationLogRequest The request for a call to `AnnotationLogService_DeleteAnnotationLog` to delete an annotation log. | Field | Type | Label | Description | | :------------------ | :----- | :---- | :-------------------------------------------------------------------------------- | | annotation\_id | string | | The ID of the parent annotation associated with the annotation log to be deleted. | | annotation\_log\_id | string | | ID of the annotation log to be deleted. | ### DeleteAnnotationLogResponse The Response of a call to `AnnotationLogService_DeleteAnnotationLog`. *This message has no fields.* ### ListAnnotationLogsRequest The request for a call to `AnnotationLogService_ListAnnotationLogs` to retrieve annotation logs. | Field | Type | Label | Description | | :------------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | annotation\_id | string | | The ID of the parent annotation associated with the annotation logs. | | page\_size | uint32 | | The maximum number of annotation logs to return. The service may return fewer than this value. If unspecified, at most 50 annotation logs will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. | | page\_token | string | | A page token, received from a previous `ListAnnotationLogs` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListAnnotationLogs` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `annotation_log_id`, `annotation_id`, `created_by_user_id`, `annotation_id`, `created_date`, `modified_date`, and `kind`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | ### ListAnnotationLogsResponse The response of a call to `AnnotationLogService_ListAnnotationLogs`. | Field | Type | Label | Description | | :---------------- | :------------------------------------------------------ | :------- | :---------- | | annotation\_logs | [AnnotationLogSearchResult](#annotationlogsearchresult) | repeated | | | next\_page\_token | string | | | ## Enums *Allowed constant values used in message fields.* ### AnnotationCommentBodyElementType | Name | Number | Description | | :------------------------------------------------------ | :----- | :---------- | | ANNOTATION\_COMMENT\_BODY\_ELEMENT\_TYPE\_UNSPECIFIED | 0 | | | ANNOTATION\_COMMENT\_BODY\_ELEMENT\_TYPE\_TEXT | 1 | | | ANNOTATION\_COMMENT\_BODY\_ELEMENT\_TYPE\_USER\_MENTION | 2 | | ### AnnotationLogKind | Name | Number | Description | | :----------------------------------- | :----- | :---------- | | ANNOTATION\_LOG\_KIND\_UNSPECIFIED | 0 | | | ANNOTATION\_LOG\_KIND\_COMMENT | 1 | | | ANNOTATION\_LOG\_KIND\_STATE\_UPDATE | 2 | | | ANNOTATION\_LOG\_KIND\_ASSIGNED | 3 | | ### AnnotationLogState | Name | Number | Description | | :---------------------------------- | :----- | :---------- | | ANNOTATION\_LOG\_STATE\_UNSPECIFIED | 0 | | | ANNOTATION\_LOG\_STATE\_CREATED | 1 | | | ANNOTATION\_LOG\_STATE\_OPEN | 2 | | | ANNOTATION\_LOG\_STATE\_FLAGGED | 3 | | | ANNOTATION\_LOG\_STATE\_RESOLVED | 4 | | # annotations Source: https://docs.siftstack.com/api/reference/protocol-buffers/annotations sift/annotations/v1/annotations.proto ## Services *RPC methods exposed by this API.* ### AnnotationService | Method | Request | Response | Description | | :------------------------ | :-------------------------------------------------------------------- | :---------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | CreateAnnotation | [CreateAnnotationRequest](#createannotationrequest) | [CreateAnnotationResponse](#createannotationresponse) | Creates an annotation. | | DeleteAnnotation | [DeleteAnnotationRequest](#deleteannotationrequest) | [DeleteAnnotationResponse](#deleteannotationresponse) | **Deprecated.** Delete Annotation is deprecated. Use ArchiveAnnotation instead. Calling this will archive the annotation, which should be done using the ArchiveAnnotation method or the UpdateAnnotation method with the delete date set to a non-null value. Restoring an annotation can be done using the UnarchiveAnnotation method or by calling UpdateAnnotation with the delete date set to a null value. | | ArchiveAnnotation | [ArchiveAnnotationRequest](#archiveannotationrequest) | [ArchiveAnnotationResponse](#archiveannotationresponse) | Archives an annotation. | | UnarchiveAnnotation | [UnarchiveAnnotationRequest](#unarchiveannotationrequest) | [UnarchiveAnnotationResponse](#unarchiveannotationresponse) | Unarchives an annotation. | | BatchDeleteAnnotations | [BatchDeleteAnnotationsRequest](#batchdeleteannotationsrequest) | [BatchDeleteAnnotationsResponse](#batchdeleteannotationsresponse) | **Deprecated.** BatchDeleteAnnotations is deprecated. Use BatchArchiveAnnotations instead. BatchDeleteAnnotations will archive the annotations specified in the request. These can be restored by calling UnarchiveAnnotation or UpdateAnnotation with the delete date set to a null value. | | BatchArchiveAnnotations | [BatchArchiveAnnotationsRequest](#batcharchiveannotationsrequest) | [BatchArchiveAnnotationsResponse](#batcharchiveannotationsresponse) | Batch archives annotations. | | BatchUnarchiveAnnotations | [BatchUnarchiveAnnotationsRequest](#batchunarchiveannotationsrequest) | [BatchUnarchiveAnnotationsResponse](#batchunarchiveannotationsresponse) | Batch unarchives annotations. | | ListAnnotations | [ListAnnotationsRequest](#listannotationsrequest) | [ListAnnotationsResponse](#listannotationsresponse) | Retrieves annotations using an optional filter. | | GetAnnotation | [GetAnnotationRequest](#getannotationrequest) | [GetAnnotationResponse](#getannotationresponse) | Retrieves an annotation | | UpdateAnnotation | [UpdateAnnotationRequest](#updateannotationrequest) | [UpdateAnnotationResponse](#updateannotationresponse) | Updates an existing annotation using using the list of fields specified in `update_mask`. | ## Messages *Data models used across requests/responses.* ### Annotation | Field | Type | Label | Description | | :---------------------------------------- | :---------------------------------------------------------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | annotation\_id | string | | | | name | string | | | | description | string | | | | start\_time | google.protobuf.Timestamp | | | | end\_time | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | run\_id | string | optional | | | state | [AnnotationState](#annotationstate) | optional | | | organization\_id | string | | | | assigned\_to\_user\_id | string | | | | annotation\_type | [AnnotationType](#annotationtype) | | | | tags | string | repeated | | | legend\_config | string | optional | | | created\_by\_condition\_id | string | optional | | | created\_by\_rule\_condition\_version\_id | string | optional | | | report\_rule\_version\_id | string | optional | | | pending | bool | | An annotation is pending if it is part of an ongoing violation of a rule condition. The `end_time` of a pending annotation might be set, but is not yet finalized. | | assigned\_to\_user | [sift.common.type.v1.User](#sift-common-type-v1-user) | | | | deleted\_date | google.protobuf.Timestamp | | **Deprecated.** | | linked\_channels | [AnnotationLinkedChannel](#annotationlinkedchannel) | repeated | | | asset\_ids | string | repeated | | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | | | archived\_date | google.protobuf.Timestamp | | | | is\_archived | bool | | is\_archived is a inferred from when archived\_date is not null | | batched\_triggers | int32 | | | | is\_noisy\_rule | bool | | | ### AnnotationLinkedCalculatedChannel | Field | Type | Label | Description | | :------------------------------- | :----- | :---- | :---------- | | calculated\_channel\_version\_id | string | | | ### AnnotationLinkedChannel | Field | Type | Label | Description | | :------------------------------ | :---------------------------------------------------------------------------------- | :---- | :---------- | | oneof type. channel | [AnnotationLinkedChannelsChannel](#annotationlinkedchannelschannel) | | | | oneof type. bit\_field\_element | [AnnotationLinkedChannelsBitFieldElement](#annotationlinkedchannelsbitfieldelement) | | | | oneof type. calculated\_channel | [AnnotationLinkedCalculatedChannel](#annotationlinkedcalculatedchannel) | | | ### AnnotationLinkedChannelsBitFieldElement | Field | Type | Label | Description | | :--------------- | :----- | :---- | :---------- | | channel\_id | string | | | | bit\_field\_name | string | | | ### AnnotationLinkedChannelsChannel | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------- | | channel\_id | string | | | ### ArchiveAnnotationRequest The request for a call to `AnnotationService_ArchiveAnnotation`. | Field | Type | Label | Description | | :------------- | :----- | :---- | :---------- | | annotation\_id | string | | | ### ArchiveAnnotationResponse The response of a call to `AnnotationService_ArchiveAnnotation`. | Field | Type | Label | Description | | :--------- | :------------------------ | :---- | :---------- | | annotation | [Annotation](#annotation) | | | ### BatchArchiveAnnotationsRequest The request for a call to `AnnotationService_BatchArchiveAnnotations`. | Field | Type | Label | Description | | :-------------- | :----- | :------- | :---------------------------------- | | annotation\_ids | string | repeated | Limit of 1000 annotations per batch | ### BatchArchiveAnnotationsResponse The response of a call to `AnnotationService_BatchArchiveAnnotations`. | Field | Type | Label | Description | | :---------- | :------------------------ | :------- | :---------- | | annotations | [Annotation](#annotation) | repeated | | ### BatchDeleteAnnotationsRequest | Field | Type | Label | Description | | :-------------- | :----- | :------- | :---------------------------------- | | annotation\_ids | string | repeated | Limit of 1000 annotations per batch | ### BatchDeleteAnnotationsResponse *This message has no fields.* ### BatchUnarchiveAnnotationsRequest The request for a call to `AnnotationService_BatchUnarchiveAnnotations`. | Field | Type | Label | Description | | :-------------- | :----- | :------- | :---------------------------------- | | annotation\_ids | string | repeated | Limit of 1000 annotations per batch | ### BatchUnarchiveAnnotationsResponse The response of a call to `AnnotationService_BatchUnarchiveAnnotations`. | Field | Type | Label | Description | | :---------- | :------------------------ | :------- | :---------- | | annotations | [Annotation](#annotation) | repeated | | ### CreateAnnotationRequest The request for a call to `AnnotationService_CreateAnnotation` to create a new annotation. At least 1 asset, tag, or channel must be specified. | Field | Type | Label | Description | | :---------------------------------------- | :---------------------------------------------------------------- | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | name | string | | The name assigned to the new annotation. | | description | string | | A short description about the new annotation. | | start\_time | google.protobuf.Timestamp | | When the annotation starts. | | end\_time | google.protobuf.Timestamp | | When the annotation ends. | | assets | string | repeated | The names of the assets to associate with this annotation. | | linked\_channels | [AnnotationLinkedChannel](#annotationlinkedchannel) | repeated | The channels to associate with this annotation. | | tags | string | repeated | The names of the tags to associate with this annotation. | | run\_id | string | optional | The ID of the run that this annotation is associated with. | | assign\_to\_user\_id | string | optional | The ID of the user that this annotation is assigned to. | | organization\_id | string | | The organization associated with this annotation. An organization ID is only required if the user belongs to multiple organizations. | | state | [AnnotationState](#annotationstate) | optional | The state of the annotation. If an annotation has an `annotation_type` of `ANNOTATION_TYPE_PHASE`, then state must be unset, otherwise an error will be returned. | | annotation\_type | [AnnotationType](#annotationtype) | | The type of the annotation. | | created\_by\_condition\_id | string | optional | The ID of the rule condition that created this annotation. | | legend\_config | string | optional | A JSON string containing the axes configuration of the annotation's linked channels. | | created\_by\_rule\_condition\_version\_id | string | optional | The ID of the rule condition version that created this annotation. | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | The metadata associated with this annotation. | ### CreateAnnotationResponse The result of a call to `AnnotationService_CreateAnnotation`. | Field | Type | Label | Description | | :--------- | :------------------------ | :---- | :---------- | | annotation | [Annotation](#annotation) | | | ### DeleteAnnotationRequest The request for a call to `AnnotationService_DeleteAnnotation`. | Field | Type | Label | Description | | :------------- | :----- | :---- | :---------- | | annotation\_id | string | | | ### DeleteAnnotationResponse The response of a call to `AnnotationService_DeleteAnnotation`. *This message has no fields.* ### GetAnnotationRequest The request for a call to `AnnotationService_GetAnnotation`. | Field | Type | Label | Description | | :------------- | :----- | :---- | :---------- | | annotation\_id | string | | | ### GetAnnotationResponse The response of a call to `AnnotationService_GetAnnotation`. | Field | Type | Label | Description | | :--------- | :------------------------ | :---- | :---------- | | annotation | [Annotation](#annotation) | | | ### ListAnnotationsRequest The request for a call to `AnnotationService_ListAnnotations` to retrieve annotations. | Field | Type | Label | Description | | :--------------- | :----- | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of annotations to return. The service may return fewer than this value. If unspecified, at most 50 annotations will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListAnnotations` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListAnnotations` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `annotation_id`, `start_time`, `end_time`, `created_date`, `modified_date`, `run_id`, `name`, `description`, `state`, `created_by_user_id`, `created_by_rule_condition_version_id`, `rule_id`, `annotation_type`, `tag_name`, `report_id`, `asset_id`, `asset_name`, `pending`, `assignee`, `campaign_reports`, `metadata`, `archived_date`, and `is_archived`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | organization\_id | string | | This field is only required if your user belongs to multiple organizations. | | order\_by | string | | How to order the retrieved annotations. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date`, `modified_date`, `start_time`, `end_time`, `name`, and `description`. If left empty, items are ordered by `created_date` in descending order (newest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | ### ListAnnotationsResponse The result of a call to `AnnotationService_ListAnnotations`. | Field | Type | Label | Description | | :---------------- | :------------------------ | :------- | :------------------------------------------------------------------------------------------------ | | annotations | [Annotation](#annotation) | repeated | | | next\_page\_token | string | | Oops, we skipped to index 5! No reason for that; the indices between aren't reserved or anything. | ### UnarchiveAnnotationRequest The request for a call to `AnnotationService_UnarchiveAnnotation`. | Field | Type | Label | Description | | :------------- | :----- | :---- | :---------- | | annotation\_id | string | | | ### UnarchiveAnnotationResponse The response of a call to `AnnotationService_UnarchiveAnnotation`. | Field | Type | Label | Description | | :--------- | :------------------------ | :---- | :---------- | | annotation | [Annotation](#annotation) | | | ### UpdateAnnotationRequest The request for a call to `AnnotationService_UpdateAnnotation` to update an annotation. | Field | Type | Label | Description | | :----------- | :------------------------------------------------------ | :---- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | annotation | [Annotation](#annotation) | | The annotation to update. | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The list of fields to be updated. The fields available to be updated are `name`, `description`, `start_time`, `end_time`, `assigned_to_user_id`, `state`, `tags`, `legend_config`, `linked_channels`, `metadata`, and `is_archived`. Prefer the ArchiveAnnotation, UnarchiveAnnotation, and batch RPCs for changing archive state. Important Note: if `tags` is specified in the update mask and `annotation.tags` is an empty list then all associated tags on the annotation will be removed. | ### UpdateAnnotationResponse The response of a call to `AnnotationService_UpdateAnnotation`. | Field | Type | Label | Description | | :--------- | :------------------------ | :---- | :---------- | | annotation | [Annotation](#annotation) | | | ## Enums *Allowed constant values used in message fields.* ### AnnotationState | Name | Number | Description | | :----------------------------- | :----- | :---------- | | ANNOTATION\_STATE\_UNSPECIFIED | 0 | | | ANNOTATION\_STATE\_OPEN | 1 | | | ANNOTATION\_STATE\_FLAGGED | 2 | | | ANNOTATION\_STATE\_RESOLVED | 3 | | ### AnnotationType | Name | Number | Description | | :----------------------------- | :----- | :---------- | | ANNOTATION\_TYPE\_UNSPECIFIED | 0 | | | ANNOTATION\_TYPE\_DATA\_REVIEW | 1 | | | ANNOTATION\_TYPE\_PHASE | 2 | | # api_keys Source: https://docs.siftstack.com/api/reference/protocol-buffers/api_keys sift/api_keys/v2/api_keys.proto ## Services *RPC methods exposed by this API.* ### ApiKeyService | Method | Request | Response | Description | | :----------------- | :------------------------------------------------------ | :-------------------------------------------------------- | :---------- | | ListApiKeys | [ListApiKeysRequest](#listapikeysrequest) | [ListApiKeysResponse](#listapikeysresponse) | | | CreateApiKey | [CreateApiKeyRequest](#createapikeyrequest) | [CreateApiKeyResponse](#createapikeyresponse) | | | DeleteApiKey | [DeleteApiKeyRequest](#deleteapikeyrequest) | [DeleteApiKeyResponse](#deleteapikeyresponse) | | | ApiKeyOrganization | [ApiKeyOrganizationRequest](#apikeyorganizationrequest) | [ApiKeyOrganizationResponse](#apikeyorganizationresponse) | | ## Messages *Data models used across requests/responses.* ### ApiKey | Field | Type | Label | Description | | :-------------------- | :------------------------ | :---- | :---------- | | api\_key\_id | string | | | | name | string | | | | created\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | user\_id | string | | | ### ApiKeyOrganizationRequest *This message has no fields.* ### ApiKeyOrganizationResponse | Field | Type | Label | Description | | :----------- | :-------------------------------------------------------------------- | :---- | :---------- | | organization | [sift.common.type.v1.Organization](#sift-common-type-v1-organization) | | | ### CreateApiKeyRequest The request for a call to ApiKeyService.CreateApiKey. | Field | Type | Label | Description | | :------- | :----- | :---- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | name | string | | The name for the new ApiKey. Required. | | user\_id | string | | The id of the user the new key will authenticate as. Must equal the id of the calling user; creating an API key on behalf of another user is no longer supported and the service will return INVALID\_ARGUMENT if the values differ. The field is retained for backwards compatibility with existing clients and may be marked deprecated in a future revision. | ### CreateApiKeyResponse | Field | Type | Label | Description | | :------- | :------------------------------ | :---- | :---------- | | api\_key | [CreatedApiKey](#createdapikey) | | | ### CreatedApiKey CreatedApiKey includes the key, which will only be returned on creation, so having a separate type makes the "never return the key a second time" semantics clear | Field | Type | Label | Description | | :-------------------- | :------------------------ | :---- | :---------- | | api\_key\_id | string | | | | name | string | | | | key | string | | | | created\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | user\_id | string | | | ### DeleteApiKeyRequest The request for a call to ApiKeyService.DeleteApiKey. | Field | Type | Label | Description | | :----------- | :----- | :---- | :---------- | | api\_key\_id | string | | | ### DeleteApiKeyResponse *This message has no fields.* ### ListApiKeysRequest The request for a call to ApiKeyService.ListApiKeys. | Field | Type | Label | Description | | :---------- | :----- | :---- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of api keys to return. The service may return fewer than this value. The maximum value is 1000; values above 1000 will be coerced to 1000. | | page\_token | string | | A page token, received from a previous `ListApiKeys` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListApiKeys` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `api_key_id`, `user_id`, `created_by_user_id`, and `name`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved channels. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `name` and `created_date`. If left empty, items are ordered by `created_date` in ascending order (oldest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "name desc,created\_date" | ### ListApiKeysResponse The result of a call to ApiKeyService.ListApiKeys. | Field | Type | Label | Description | | :---------------- | :---------------- | :------- | :---------- | | api\_keys | [ApiKey](#apikey) | repeated | | | next\_page\_token | string | | | ## Enums *Allowed constant values used in message fields.* # artifacts Source: https://docs.siftstack.com/api/reference/protocol-buffers/artifacts sift/artifacts/v1/artifacts.proto ## Services *RPC methods exposed by this API.* ### ArtifactService ArtifactService manages artifacts: independent, org-scoped, versioned documents. An artifact is not owned by a conversation. A conversation may reference an artifact through a link, any number of conversations may link the same artifact, and an artifact may exist with no link at all (for example, created over MCP outside an agent session). The service carries artifact metadata only. Version bytes live in remote\_files (entity\_type 'artifact\_versions', entity\_id = artifact\_version\_id): upload via the remote-files multipart endpoint, download via RemoteFileService.GetRemoteFileDownloadUrl. | Method | Request | Response | Description | | :----------------------------- | :------------------------------------------------------------------------------ | :-------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | CreateArtifact | [CreateArtifactRequest](#createartifactrequest) | [CreateArtifactResponse](#createartifactresponse) | Creates an artifact plus its version-1 row, or appends a version when artifact\_id is set. When conversation\_id is set on create, the new artifact is also linked to that conversation. | | GetArtifact | [GetArtifactRequest](#getartifactrequest) | [GetArtifactResponse](#getartifactresponse) | Resolves to the latest version unless artifact\_version\_id pins one. | | ListArtifacts | [ListArtifactsRequest](#listartifactsrequest) | [ListArtifactsResponse](#listartifactsresponse) | One entry per artifact, resolved to its latest version, oldest first. With conversation\_id set, only artifacts linked to that conversation; otherwise every artifact in the caller's organization. | | ListArtifactVersions | [ListArtifactVersionsRequest](#listartifactversionsrequest) | [ListArtifactVersionsResponse](#listartifactversionsresponse) | Full version history of one artifact, newest first. | | LinkArtifactToConversation | [LinkArtifactToConversationRequest](#linkartifacttoconversationrequest) | [LinkArtifactToConversationResponse](#linkartifacttoconversationresponse) | Links an existing artifact to a conversation. Idempotent: linking an already-linked pair succeeds without effect. | | UnlinkArtifactFromConversation | [UnlinkArtifactFromConversationRequest](#unlinkartifactfromconversationrequest) | [UnlinkArtifactFromConversationResponse](#unlinkartifactfromconversationresponse) | Removes one conversation's link to an artifact. The artifact itself is untouched. Idempotent: unlinking a missing link succeeds. | | ArchiveArtifact | [ArchiveArtifactRequest](#archiveartifactrequest) | [ArchiveArtifactResponse](#archiveartifactresponse) | Sets archived\_date. Versions, stored bytes, and conversation links are left in place. Idempotent: archiving an already-archived artifact succeeds without changing archived\_date. | | UnarchiveArtifact | [UnarchiveArtifactRequest](#unarchiveartifactrequest) | [UnarchiveArtifactResponse](#unarchiveartifactresponse) | Clears archived\_date. Idempotent: unarchiving an active artifact succeeds without effect. | ## Messages *Data models used across requests/responses.* ### ArchiveArtifactRequest | Field | Type | Label | Description | | :----------- | :----- | :---- | :---------- | | artifact\_id | string | | | ### ArchiveArtifactResponse *This message has no fields.* ### Artifact Container fields flattened together with one resolved version. | Field | Type | Label | Description | | :--------------------- | :---------------------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | artifact\_id | string | | | | organization\_id | string | | | | created\_by\_user\_id | string | | | | authoring\_kind | [ArtifactAuthoringKind](#artifactauthoringkind) | | | | created\_date | google.protobuf.Timestamp | | | | artifact\_version\_id | string | | | | version | uint32 | | | | title | string | optional | | | summary | string | optional | | | authoring\_message\_id | string | optional | Set only for versions authored inside a conversation, and there only after the introducing message persists: uploads attach before the user sends, and agent turns persist messages only at end of turn. | | source\_tool\_use\_ids | string | repeated | | | remote\_file\_id | string | optional | Unset until bytes are uploaded. | | version\_created\_date | google.protobuf.Timestamp | | | | file\_name | string | optional | From the version's remote\_files row. Unset until bytes are uploaded. Clients infer preview behavior from file\_name / file\_mime\_type. | | file\_mime\_type | string | optional | | | archived\_date | google.protobuf.Timestamp | optional | Unset while the artifact is active. | ### ArtifactVersion | Field | Type | Label | Description | | :--------------------- | :------------------------ | :------- | :-------------------------------------------------------------------- | | artifact\_version\_id | string | | | | artifact\_id | string | | | | version | uint32 | | | | title | string | optional | | | summary | string | optional | | | authoring\_message\_id | string | optional | | | source\_tool\_use\_ids | string | repeated | | | remote\_file\_id | string | optional | | | created\_date | google.protobuf.Timestamp | | | | file\_name | string | optional | From the version's remote\_files row. Unset until bytes are uploaded. | | file\_mime\_type | string | optional | | ### CreateArtifactRequest | Field | Type | Label | Description | | :--------------- | :---------------------------------------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | artifact\_id | string | optional | Set to append a version to an existing artifact; unset to create one. | | conversation\_id | string | optional | Set to link the new artifact to a conversation at create time. Legal only on create (not on append), and only for the conversation's author. | | title | string | optional | | | summary | string | optional | | | authoring\_kind | [ArtifactAuthoringKind](#artifactauthoringkind) | optional | Defaults to USER. AGENT is self-reported: the agent pod authenticates with the requesting user's transient key, so until scoped pod credentials land (ENG-12831) authorship attribution rides on the same trust as the pod's message persistence path. | ### CreateArtifactResponse | Field | Type | Label | Description | | :------- | :-------------------- | :---- | :---------- | | artifact | [Artifact](#artifact) | | | ### GetArtifactRequest | Field | Type | Label | Description | | :-------------------- | :----- | :------- | :---------- | | artifact\_id | string | | | | artifact\_version\_id | string | optional | | ### GetArtifactResponse | Field | Type | Label | Description | | :------- | :-------------------- | :---- | :---------- | | artifact | [Artifact](#artifact) | | | ### LinkArtifactToConversationRequest | Field | Type | Label | Description | | :--------------- | :----- | :---- | :---------- | | artifact\_id | string | | | | conversation\_id | string | | | ### LinkArtifactToConversationResponse *This message has no fields.* ### ListArtifactVersionsRequest | Field | Type | Label | Description | | :----------- | :----- | :---- | :---------- | | artifact\_id | string | | | | page\_size | uint32 | | | | page\_token | string | | | ### ListArtifactVersionsResponse | Field | Type | Label | Description | | :---------------- | :---------------------------------- | :------- | :---------- | | versions | [ArtifactVersion](#artifactversion) | repeated | | | next\_page\_token | string | | | ### ListArtifactsRequest | Field | Type | Label | Description | | :---------------- | :----- | :------- | :-------------------------------------------------------- | | conversation\_id | string | optional | Unset lists every artifact in the caller's organization. | | page\_size | uint32 | | | | page\_token | string | | | | include\_archived | bool | | When false (the default), archived artifacts are omitted. | ### ListArtifactsResponse | Field | Type | Label | Description | | :---------------- | :-------------------- | :------- | :---------- | | artifacts | [Artifact](#artifact) | repeated | | | next\_page\_token | string | | | ### UnarchiveArtifactRequest | Field | Type | Label | Description | | :----------- | :----- | :---- | :---------- | | artifact\_id | string | | | ### UnarchiveArtifactResponse *This message has no fields.* ### UnlinkArtifactFromConversationRequest | Field | Type | Label | Description | | :--------------- | :----- | :---- | :---------- | | artifact\_id | string | | | | conversation\_id | string | | | ### UnlinkArtifactFromConversationResponse *This message has no fields.* ## Enums *Allowed constant values used in message fields.* ### ArtifactAuthoringKind | Name | Number | Description | | :------------------------------------- | :----- | :---------- | | ARTIFACT\_AUTHORING\_KIND\_UNSPECIFIED | 0 | | | ARTIFACT\_AUTHORING\_KIND\_AGENT | 1 | | | ARTIFACT\_AUTHORING\_KIND\_USER | 2 | | # assets Source: https://docs.siftstack.com/api/reference/protocol-buffers/assets sift/assets/v1/assets.proto ## Services *RPC methods exposed by this API.* ### AssetService | Method | Request | Response | Description | | :----------- | :------------------------------------------ | :-------------------------------------------- | :---------------------------------------------------------------------------------- | | DeleteAsset | [DeleteAssetRequest](#deleteassetrequest) | [DeleteAssetResponse](#deleteassetresponse) | **Deprecated.** Delete will archive an asset. Deprecated: Use ArchiveAsset instead. | | CreateAsset | [CreateAssetRequest](#createassetrequest) | [CreateAssetResponse](#createassetresponse) | Creates a new, empty asset. | | GetAsset | [GetAssetRequest](#getassetrequest) | [GetAssetResponse](#getassetresponse) | Retrieves an asset. | | ListAssets | [ListAssetsRequest](#listassetsrequest) | [ListAssetsResponse](#listassetsresponse) | Retrieves assets using an optional filter. | | UpdateAsset | [UpdateAssetRequest](#updateassetrequest) | [UpdateAssetResponse](#updateassetresponse) | | | ArchiveAsset | [ArchiveAssetRequest](#archiveassetrequest) | [ArchiveAssetResponse](#archiveassetresponse) | Archive an asset. | ## Messages *Data models used across requests/responses.* ### ArchiveAssetRequest The request for a call to `AssetService_ArchiveAsset` to archive a single existing asset by its asset\_id. | Field | Type | Label | Description | | :------------ | :----- | :---- | :-------------------------------------------------------- | | asset\_id | string | | The id of the asset to be archived. Required. | | archive\_runs | bool | | If true, will archive all runs associated with the asset. | ### ArchiveAssetResponse The response of a call to `AssetService_ArchiveAsset`. | Field | Type | Label | Description | | :----------------- | :----- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | archived\_run\_ids | string | repeated | List of run IDs that were archived when archive\_runs was set to true. This field will be empty if archive\_runs was false or if no runs were archived. | ### Asset | Field | Type | Label | Description | | :--------------------- | :---------------------------------------------------------------- | :------- | :---------------------------------------------------------------------------------- | | asset\_id | string | | | | name | string | | | | organization\_id | string | | | | created\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_date | google.protobuf.Timestamp | | | | modified\_by\_user\_id | string | | | | tags | string | repeated | The names of the tags associated with this asset. | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | The metadata values associated with this asset. | | archived\_date | google.protobuf.Timestamp | | The date the asset was archived. | | is\_archived | bool | | Whether the asset is archived. This is inferred from whether archived\_date is set. | ### CreateAssetRequest The request for a call to `AssetService_CreateAsset` to create a single new, empty asset. | Field | Type | Label | Description | | :------- | :---------------------------------------------------------------- | :------- | :--------------------------------------------------------------------------------- | | name | string | | The name of the asset to create. Must be unique within the organization. Required. | | tags | string | repeated | The names of the tags to associate with this asset. Optional. | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | The metadata values to associate with this asset. Optional. | ### CreateAssetResponse The response of a call to `AssetService_CreateAsset`. | Field | Type | Label | Description | | :---- | :-------------- | :---- | :----------------------- | | asset | [Asset](#asset) | | The newly created asset. | ### DeleteAssetRequest The request for a call to `AssetService_DeleteAsset` to archive a single existing asset by its asset\_id. Deprecated: Use ArchiveAssetRequest instead. | Field | Type | Label | Description | | :------------ | :----- | :---- | :-------------------------------------------------------- | | asset\_id | string | | The id of the asset to be archived. Required. | | archive\_runs | bool | | If true, will archive all runs associated with the asset. | ### DeleteAssetResponse The response of a call to `AssetService_DeleteAsset`. Deprecated: Use ArchiveAssetResponse instead. *This message has no fields.* ### GetAssetRequest The request for a call to `AssetService_GetAsset` to retrieve a single existing asset by its asset\_id. | Field | Type | Label | Description | | :-------- | :----- | :---- | :--------------------------------------------- | | asset\_id | string | | The id of the asset to be retrieved. Required. | ### GetAssetResponse | Field | Type | Label | Description | | :---- | :-------------- | :---- | :---------- | | asset | [Asset](#asset) | | | ### ListAssetsRequest The request for a call to `AssetService_ListAssets`. | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of assets to return. The service may return fewer than this value. If unspecified, at most 50 assets will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. | | page\_token | string | | A page token, received from a previous `ListAssets` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListAssets` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `asset_id`, `created_by_user_id`, `modified_by_user_id`, `created_date`, `modified_date`, `name`, 'name\_lower', `tag_id`, `tag_name`, 'archived\_date', `is_archived`, and `metadata`. Metadata can be used in filters by using `metadata.{metadata_key_name}` as the field name. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved assets. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `name`, `created_date`, `modified_date` and `archived_date`. If left empty, items are ordered by `created_date` in descending order (newest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | ### ListAssetsResponse The result of a call to `AssetService_ListAssets`. | Field | Type | Label | Description | | :---------------- | :-------------- | :------- | :---------- | | assets | [Asset](#asset) | repeated | | | next\_page\_token | string | | | ### UpdateAssetRequest The request for a call to `AssetService_UpdateAsset` to update a single existing asset. | Field | Type | Label | Description | | :----------- | :------------------------------------------------------ | :---- | :------------------------------------------------------------------------------------------------------------------------------- | | asset | [Asset](#asset) | | The asset to update. The asset's `asset_id` field is used to identify asset run to update and is required. | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The list of fields to be updated. The fields available to be updated are `tags`, `metadata`, `archived_date`, and `is_archived`. | ### UpdateAssetResponse The response of a call to `AssetService_UpdateAsset`. | Field | Type | Label | Description | | :---- | :-------------- | :---- | :---------- | | asset | [Asset](#asset) | | | ## Enums *Allowed constant values used in message fields.* # automation Source: https://docs.siftstack.com/api/reference/protocol-buffers/automation sift/automation/v1/automation.proto ## Services *RPC methods exposed by this API.* ### AutomationService AutomationService manages Canvas Scheduler automation triggers. An automation trigger fires when a producer (v1: RunService.StopRun) observes a Run whose metadata matches the trigger's match filter; the resulting automation\_triggered\_events row is dispatched by the automation worker after a bounded wait, currently by calling CanvasService.EvaluateCanvas. | Method | Request | Response | Description | | :---------------------------- | :---------------------------------------------------------------------------- | :------------------------------------------------------------------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GetAutomationTrigger | [GetAutomationTriggerRequest](#getautomationtriggerrequest) | [GetAutomationTriggerResponse](#getautomationtriggerresponse) | Retrieve an automation trigger by ID. | | CreateAutomationTrigger | [CreateAutomationTriggerRequest](#createautomationtriggerrequest) | [CreateAutomationTriggerResponse](#createautomationtriggerresponse) | Create an automation trigger. | | UpdateAutomationTrigger | [UpdateAutomationTriggerRequest](#updateautomationtriggerrequest) | [UpdateAutomationTriggerResponse](#updateautomationtriggerresponse) | Update select fields of an existing automation trigger. To enable or disable a trigger set the `is_enabled` field and include `is_enabled` in the update mask. | | ListAutomationTriggers | [ListAutomationTriggersRequest](#listautomationtriggersrequest) | [ListAutomationTriggersResponse](#listautomationtriggersresponse) | Retrieve and optionally filter a list of automation triggers. | | DeleteAutomationTrigger | [DeleteAutomationTriggerRequest](#deleteautomationtriggerrequest) | [DeleteAutomationTriggerResponse](#deleteautomationtriggerresponse) | Delete an automation trigger. Soft-delete: sets `archived_date` and hides the trigger from further producer matches. Historical `automation_triggered_events` rows survive for the retention window so past dispatches can still be inspected. | | ListAutomationTriggeredEvents | [ListAutomationTriggeredEventsRequest](#listautomationtriggeredeventsrequest) | [ListAutomationTriggeredEventsResponse](#listautomationtriggeredeventsresponse) | Retrieve and optionally filter a list of automation triggered events (per-trigger dispatch history). Filter by `automation_trigger_id` to power the canvas trigger history sidebar, or by `state == FAILED` for the manage jobs automation errors tab. Match/config and dispatch failures set `last_error`. | ## Messages *Data models used across requests/responses.* ### AutomationTrigger | Field | Type | Label | Description | | :------------------------------ | :-------------------------------------------------------------- | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | automation\_trigger\_id | string | | | | organization\_id | string | | | | canvas\_id | string | | | | name | string | | | | match\_filter | [AutomationTriggerMatchFilter](#automationtriggermatchfilter) | | | | user\_id | string | | Impersonation user materialized at create time. Recheck happens at dispatch when the automation worker impersonates this user for the EvaluateCanvas call. | | action\_kind | [AutomationTriggerActionKind](#automationtriggeractionkind) | | | | action\_params | [AutomationTriggerActionParams](#automationtriggeractionparams) | | Typed template action params. Must agree with `action_kind` (e.g. CANVAS\_EVALUATION requires `action_params.canvas_evaluation`). The match job resolves wildcards into automation\_triggered\_events.action\_params\_snapshot; the automation worker pass-throughs that snapshot to EvaluateCanvas. | | is\_enabled | bool | | | | archived\_date | google.protobuf.Timestamp | optional | | | is\_archived | bool | | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | email\_notifications\_enabled | bool | | When true, dispatches also send an email to notification\_recipient\_emails. The in-app notification to the trigger's creator is always created. Defaults to true. | | notification\_recipient\_emails | string | repeated | Addresses emailed when this trigger dispatches. Plain addresses rather than user ids, so reports can reach shared inboxes, ticket bots and distribution lists. Empty falls back to the creator's address. | ### AutomationTriggerActionParams AutomationTriggerActionParams is the public action\_params shape. oneof by action kind so future dispatch types (webhook, email, ...) don't fall back to google.protobuf.Struct. | Field | Type | Label | Description | | :----------------------------- | :------------------------------------------------------------ | :---- | :---------- | | oneof kind. canvas\_evaluation | [CanvasEvaluationActionParams](#canvasevaluationactionparams) | | | ### AutomationTriggerMatchFilter AutomationTriggerMatchFilter is the selector evaluated asynchronously after StopRun. StopRun inserts an automation\_source\_event (RUN\_STOP); the automation\_worker then pages through the org's enabled, non-archived automation\_triggers and enqueues a row for each trigger whose match\_filter accepts the run (the trigger's canvas\_id identifies which canvas to evaluate later — runs themselves have no canvas association). Empty asset\_ids matches any asset; absent name\_match matches any name; empty metadata\_matches matches any metadata. Dimensions are AND'd. Name matching for STARTS\_WITH / ENDS\_WITH / CONTAINS is case-insensitive; REGEX uses Go regexp semantics (add (?i) for case-insensitive patterns). | Field | Type | Label | Description | | :---------------- | :---------------------------------------------------------------- | :------- | :---------- | | asset\_ids | string | repeated | | | name\_match | [AutomationTriggerRunNameMatch](#automationtriggerrunnamematch) | optional | | | metadata\_matches | [AutomationTriggerMetadataMatch](#automationtriggermetadatamatch) | repeated | | ### AutomationTriggerMetadataMatch AutomationTriggerMetadataMatch is an equality filter against a run's entity-metadata key/value. Key names are case-sensitive. Values are compared as strings (numbers/booleans are stringified with Go's default formatting). All listed matches are AND'd together. | Field | Type | Label | Description | | :---- | :----- | :---- | :---------- | | key | string | | | | value | string | | | ### AutomationTriggerParamValue AutomationTriggerParamValue is one canvas param: a JSON literal or a run-scoped wildcard source. Prefer this over ad-hoc `{"source":"..."}` objects in a free-form Struct. | Field | Type | Label | Description | | :------------------- | :------------------------------------------------------------ | :---- | :---------- | | oneof value. literal | google.protobuf.Value | | | | oneof value. source | [AutomationTriggerParamSource](#automationtriggerparamsource) | | | ### AutomationTriggerRunNameMatch AutomationTriggerRunNameMatch expresses a filter against runs.name. | Field | Type | Label | Description | | :---- | :---------------------------------------------------------------------- | :---- | :---------- | | kind | [AutomationTriggerRunNameMatchKind](#automationtriggerrunnamematchkind) | | | | value | string | | | ### AutomationTriggeredEvent AutomationTriggeredEvent is one (automation\_trigger, run) match. When dispatch succeeds, `canvas_execution_id` points at the resulting canvas\_executions row (and published report, when publish=true). | Field | Type | Label | Description | | :------------------------------- | :-------------------------------------------------------------- | :------- | :---------- | | automation\_triggered\_event\_id | string | | | | organization\_id | string | | | | automation\_trigger\_id | string | | | | run\_id | string | | | | state | [AutomationTriggeredEventState](#automationtriggeredeventstate) | | | | dispatch\_after | google.protobuf.Timestamp | | | | canvas\_execution\_id | string | optional | | | attempt\_count | int32 | | | | last\_error | string | optional | | | terminal\_date | google.protobuf.Timestamp | optional | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | ### CanvasEvaluationActionParams CanvasEvaluationActionParams is the typed template for AUTOMATION\_TRIGGER\_ACTION\_KIND\_CANVAS\_EVALUATION. Wildcards in param\_json are resolved into automation\_triggered\_events.action\_params\_snapshot; the automation worker pass-throughs that snapshot to EvaluateCanvas. | Field | Type | Label | Description | | :------------------ | :------------------------------------------------------------------------------------------ | :------- | :---------- | | canvas\_version\_id | string | | | | param\_json | [CanvasEvaluationActionParams.ParamJsonEntry](#canvasevaluationactionparams-paramjsonentry) | repeated | | ### CanvasEvaluationActionParams.ParamJsonEntry | Field | Type | Label | Description | | :---- | :---------------------------------------------------------- | :---- | :---------- | | key | string | | | | value | [AutomationTriggerParamValue](#automationtriggerparamvalue) | | | ### CreateAutomationTriggerRequest The request for a call to `AutomationService_CreateAutomationTrigger`. | Field | Type | Label | Description | | :------------------------------ | :-------------------------------------------------------------- | :------- | :-------------------------------------------------- | | canvas\_id | string | | | | name | string | | | | match\_filter | [AutomationTriggerMatchFilter](#automationtriggermatchfilter) | | | | action\_kind | [AutomationTriggerActionKind](#automationtriggeractionkind) | | | | action\_params | [AutomationTriggerActionParams](#automationtriggeractionparams) | | | | is\_enabled | bool | optional | | | email\_notifications\_enabled | bool | optional | Defaults to true when unset. | | notification\_recipient\_emails | string | repeated | Defaults to the creating user's address when empty. | ### CreateAutomationTriggerResponse The response of a call to `AutomationService_CreateAutomationTrigger`. | Field | Type | Label | Description | | :------------------ | :-------------------------------------- | :---- | :---------- | | automation\_trigger | [AutomationTrigger](#automationtrigger) | | | ### DeleteAutomationTriggerRequest The request for a call to `AutomationService_DeleteAutomationTrigger`. Soft-deletes by setting archived\_date. | Field | Type | Label | Description | | :---------------------- | :----- | :---- | :---------- | | automation\_trigger\_id | string | | | ### DeleteAutomationTriggerResponse The response of a call to `AutomationService_DeleteAutomationTrigger`. *This message has no fields.* ### GetAutomationTriggerRequest The request for a call to `AutomationService_GetAutomationTrigger`. | Field | Type | Label | Description | | :---------------------- | :----- | :---- | :---------- | | automation\_trigger\_id | string | | | ### GetAutomationTriggerResponse The response of a call to `AutomationService_GetAutomationTrigger`. | Field | Type | Label | Description | | :------------------ | :-------------------------------------- | :---- | :---------- | | automation\_trigger | [AutomationTrigger](#automationtrigger) | | | ### ListAutomationTriggeredEventsRequest The request for a call to `AutomationService_ListAutomationTriggeredEvents`. | Field | Type | Label | Description | | :---------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------ | | page\_size | uint32 | | | | page\_token | string | | | | filter | string | | CEL filter. Available fields: `automation_triggered_event_id`, `automation_trigger_id`, `automation_trigger_name`, `run_id`, `run_name`, `state`. | | order\_by | string | | Order-by. Available fields: `created_date`, `dispatch_after`. Default: `created_date desc`. | ### ListAutomationTriggeredEventsResponse The response of a call to `AutomationService_ListAutomationTriggeredEvents`. | Field | Type | Label | Description | | :---------------------------- | :---------------------------------------------------- | :------- | :---------- | | automation\_triggered\_events | [AutomationTriggeredEvent](#automationtriggeredevent) | repeated | | | next\_page\_token | string | | | ### ListAutomationTriggersRequest The request for a call to `AutomationService_ListAutomationTriggers`. | Field | Type | Label | Description | | :---------- | :----- | :---- | :--------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | | | page\_token | string | | | | filter | string | | CEL filter. Available fields: `automation_trigger_id`, `canvas_id`, `name`, `action_kind`, `is_enabled`, `is_archived`, `archived_date`. | | order\_by | string | | Order-by. Available fields: `created_date`, `modified_date`, `name`. Default: `created_date desc`. | ### ListAutomationTriggersResponse The response of a call to `AutomationService_ListAutomationTriggers`. | Field | Type | Label | Description | | :------------------- | :-------------------------------------- | :------- | :---------- | | automation\_triggers | [AutomationTrigger](#automationtrigger) | repeated | | | next\_page\_token | string | | | ### UpdateAutomationTriggerRequest The request for a call to `AutomationService_UpdateAutomationTrigger`. The trigger's `automation_trigger_id` is used to identify the row; every other field is applied only when named in `update_mask`. | Field | Type | Label | Description | | :------------------ | :------------------------------------------------------ | :---- | :---------- | | automation\_trigger | [AutomationTrigger](#automationtrigger) | | | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | | ### UpdateAutomationTriggerResponse The response of a call to `AutomationService_UpdateAutomationTrigger`. To archive a trigger, include `archived_date` in the mask and set the field. To unarchive, include `archived_date` in the mask and clear it. | Field | Type | Label | Description | | :------------------ | :-------------------------------------- | :---- | :---------- | | automation\_trigger | [AutomationTrigger](#automationtrigger) | | | ## Enums *Allowed constant values used in message fields.* ### AutomationTriggerActionKind AutomationTriggerActionKind is what an automation trigger does when it fires. v1 supports `AUTOMATION_TRIGGER_ACTION_KIND_CANVAS_EVALUATION` only; the enum is kept so future dispatch types (webhook, email, ...) can be added without a breaking change. | Name | Number | Description | | :---------------------------------------------------- | :----- | :---------- | | AUTOMATION\_TRIGGER\_ACTION\_KIND\_UNSPECIFIED | 0 | | | AUTOMATION\_TRIGGER\_ACTION\_KIND\_CANVAS\_EVALUATION | 1 | | ### AutomationTriggerParamSource AutomationTriggerParamSource is a wildcard resolved against the triggering run when the match job builds action\_params\_snapshot. | Name | Number | Description | | :---------------------------------------------------------- | :----- | :---------------------------------------------------------- | | AUTOMATION\_TRIGGER\_PARAM\_SOURCE\_UNSPECIFIED | 0 | | | AUTOMATION\_TRIGGER\_PARAM\_SOURCE\_TRIGGERING\_RUN | 1 | Resolves to the triggering run's run\_id (string). | | AUTOMATION\_TRIGGER\_PARAM\_SOURCE\_TRIGGERING\_RUN\_ASSETS | 2 | Resolves to the triggering run's asset\_ids (string array). | ### AutomationTriggerRunNameMatchKind AutomationTriggerRunNameMatchKind is the operator on runs.name in an automation trigger match filter. | Name | Number | Description | | :-------------------------------------------------------- | :----- | :---------- | | AUTOMATION\_TRIGGER\_RUN\_NAME\_MATCH\_KIND\_UNSPECIFIED | 0 | | | AUTOMATION\_TRIGGER\_RUN\_NAME\_MATCH\_KIND\_STARTS\_WITH | 1 | | | AUTOMATION\_TRIGGER\_RUN\_NAME\_MATCH\_KIND\_ENDS\_WITH | 2 | | | AUTOMATION\_TRIGGER\_RUN\_NAME\_MATCH\_KIND\_CONTAINS | 3 | | | AUTOMATION\_TRIGGER\_RUN\_NAME\_MATCH\_KIND\_REGEX | 4 | | ### AutomationTriggeredEventState AutomationTriggeredEventState is the lifecycle of a single (automation\_trigger, run) match / dispatch attempt. | Name | Number | Description | | :----------------------------------------------- | :----- | :---------- | | AUTOMATION\_TRIGGERED\_EVENT\_STATE\_UNSPECIFIED | 0 | | | AUTOMATION\_TRIGGERED\_EVENT\_STATE\_WAITING | 1 | | | AUTOMATION\_TRIGGERED\_EVENT\_STATE\_DISPATCHING | 2 | | | AUTOMATION\_TRIGGERED\_EVENT\_STATE\_DONE | 3 | | | AUTOMATION\_TRIGGERED\_EVENT\_STATE\_FAILED | 4 | | | AUTOMATION\_TRIGGERED\_EVENT\_STATE\_CANCELLED | 5 | | # calculated_channels Source: https://docs.siftstack.com/api/reference/protocol-buffers/calculated_channels sift/calculated_channels/v2/calculated_channels.proto ## Services *RPC methods exposed by this API.* ### CalculatedChannelService | Method | Request | Response | Description | | :----------------------------- | :------------------------------------------------------------------------------ | :-------------------------------------------------------------------------------- | :------------------------------------------------------------------------------- | | GetCalculatedChannel | [GetCalculatedChannelRequest](#getcalculatedchannelrequest) | [GetCalculatedChannelResponse](#getcalculatedchannelresponse) | Retrieve the latest version of a calculated channel | | CreateCalculatedChannel | [CreateCalculatedChannelRequest](#createcalculatedchannelrequest) | [CreateCalculatedChannelResponse](#createcalculatedchannelresponse) | Create a calculated channel. | | ListCalculatedChannels | [ListCalculatedChannelsRequest](#listcalculatedchannelsrequest) | [ListCalculatedChannelsResponse](#listcalculatedchannelsresponse) | Retrieve the latest versions of calculated channels based on an optional filter. | | UpdateCalculatedChannel | [UpdateCalculatedChannelRequest](#updatecalculatedchannelrequest) | [UpdateCalculatedChannelResponse](#updatecalculatedchannelresponse) | Update and create a new version of a calculated channel. | | ListCalculatedChannelVersions | [ListCalculatedChannelVersionsRequest](#listcalculatedchannelversionsrequest) | [ListCalculatedChannelVersionsResponse](#listcalculatedchannelversionsresponse) | List versions of a particular calculated channel with an optional filter. | | ResolveCalculatedChannel | [ResolveCalculatedChannelRequest](#resolvecalculatedchannelrequest) | [ResolveCalculatedChannelResponse](#resolvecalculatedchannelresponse) | Resolve a calculated channel into an expression with references. | | BatchResolveCalculatedChannels | [BatchResolveCalculatedChannelsRequest](#batchresolvecalculatedchannelsrequest) | [BatchResolveCalculatedChannelsResponse](#batchresolvecalculatedchannelsresponse) | Resolve a batch of calculated channels into expressions with references. | | ListResolvedCalculatedChannels | [ListResolvedCalculatedChannelsRequest](#listresolvedcalculatedchannelsrequest) | [ListResolvedCalculatedChannelsResponse](#listresolvedcalculatedchannelsresponse) | Retrieve the latest versions of calculated channels based on an optional filter. | | GetCalculatedChannelVersions | [GetCalculatedChannelVersionsRequest](#getcalculatedchannelversionsrequest) | [GetCalculatedChannelVersionsResponse](#getcalculatedchannelversionsresponse) | Retrieve calculated channel versions by their version IDs. | | GetCalculatedChannelDependents | [GetCalculatedChannelDependentsRequest](#getcalculatedchanneldependentsrequest) | [GetCalculatedChannelDependentsResponse](#getcalculatedchanneldependentsresponse) | Retrieve calculated channels that depend on a given calculated channel. | ## Messages *Data models used across requests/responses.* ### BatchResolveCalculatedChannelsRequest The request of a call to `CalculatedChannelService_BatchResolveCalculatedChannels`. | Field | Type | Label | Description | | :------- | :------------------------------------------------------------------ | :------- | :---------------------------------- | | requests | [ResolveCalculatedChannelRequest](#resolvecalculatedchannelrequest) | repeated | All calculated channels to resolve. | ### BatchResolveCalculatedChannelsResponse The response of a call to `CalculatedChannelService_BatchResolveCalculatedChannels`. | Field | Type | Label | Description | | :-------- | :-------------------------------------------------------------------- | :------- | :------------------------------------------------- | | responses | [ResolveCalculatedChannelResponse](#resolvecalculatedchannelresponse) | repeated | All calculated channels that attempted resolution. | ### CalculatedChannel | Field | Type | Label | Description | | :--------------------------------- | :-------------------------------------------------------------------------------- | :------- | :----------------------------------------------------------------------------------------------- | | calculated\_channel\_id | string | | | | organization\_id | string | | | | client\_key | string | optional | | | archived\_date | google.protobuf.Timestamp | optional | | | version\_id | string | | | | version | uint32 | | | | name | string | | | | description | string | | | | change\_message | string | | | | user\_notes | string | | | | units | string | optional | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | calculated\_channel\_configuration | [CalculatedChannelConfiguration](#calculatedchannelconfiguration) | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | function\_dependencies | [sift.common.type.v1.FunctionDependency](#sift-common-type-v1-functiondependency) | repeated | | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | | | is\_archived | bool | | Whether the calculated channel is archived. This is inferred from whether archived\_date is set. | | calculated\_channel\_dependencies | [CalculatedChannelDependency](#calculatedchanneldependency) | repeated | Calculated channels that this channel depends on. | | folder\_ids | string | repeated | Ids of the folders this calculated channel belongs to. | ### CalculatedChannelAbstractChannelReference | Field | Type | Label | Description | | :--------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------- | :---- | :---------------------------------------------------------------------------------- | | channel\_reference | string | | | | channel\_identifier | string | | must use either a channel\_identifier or a calculated\_channel\_reference, not both | | oneof calculated\_channel\_reference. calculated\_channel\_version\_id | string | | | | oneof calculated\_channel\_reference. calculated\_channel | [sift.calculated\_channels.v1.ExpressionRequest](#sift-calculated_channels-v1-expressionrequest) | | | ### CalculatedChannelAssetConfiguration | Field | Type | Label | Description | | :------------------------------ | :-------------------------------------------------------------------------------------------------------- | :---- | :---------- | | oneof asset\_scope. all\_assets | bool | | | | oneof asset\_scope. selection | [CalculatedChannelAssetConfiguration.AssetSelection](#calculatedchannelassetconfiguration-assetselection) | | | ### CalculatedChannelAssetConfiguration.AssetSelection | Field | Type | Label | Description | | :--------- | :----- | :------- | :---------- | | asset\_ids | string | repeated | | | tag\_ids | string | repeated | | ### CalculatedChannelConfiguration | Field | Type | Label | Description | | :------------------- | :-------------------------------------------------------------------------- | :---- | :---------- | | asset\_configuration | [CalculatedChannelAssetConfiguration](#calculatedchannelassetconfiguration) | | | | query\_configuration | [CalculatedChannelQueryConfiguration](#calculatedchannelqueryconfiguration) | | | ### CalculatedChannelDependency A dependency on another calculated channel. | Field | Type | Label | Description | | :------------------------------- | :----- | :---- | :---------- | | calculated\_channel\_version\_id | string | | | ### CalculatedChannelQueryConfiguration | Field | Type | Label | Description | | :--------------- | :---------------------------------------------------------------------------------- | :---- | :---------- | | oneof query. sel | [CalculatedChannelQueryConfiguration.Sel](#calculatedchannelqueryconfiguration-sel) | | | ### CalculatedChannelQueryConfiguration.Sel Sift Expression Language. | Field | Type | Label | Description | | :------------------------------ | :-------------------------------------------------------------------------------------- | :------- | :---------- | | expression | string | | | | expression\_channel\_references | [CalculatedChannelAbstractChannelReference](#calculatedchannelabstractchannelreference) | repeated | | ### CalculatedChannelResolution | Field | Type | Label | Description | | :------------------ | :---------------------------------------------------------- | :------- | :---------------------------------------- | | calculated\_channel | [CalculatedChannel](#calculatedchannel) | optional | The calculated channel resolved. | | resolved | [ResolvedCalculatedChannel](#resolvedcalculatedchannel) | repeated | All resolved calculated channels. | | unresolved | [UnresolvedCalculatedChannel](#unresolvedcalculatedchannel) | repeated | All assets with any issues in resolution. | ### CalculatedChannelValidationResult | Field | Type | Label | Description | | :---------------- | :----- | :------- | :---------------------------------------------- | | asset\_id | string | | | | asset\_name | string | optional | Only included if asset was named in the request | | tag\_names | string | repeated | Includes all tags that have this asset | | missing\_channels | string | repeated | Names of the channels that asset does not have | ### CreateCalculatedChannelRequest | Field | Type | Label | Description | | :--------------------------------- | :---------------------------------------------------------------- | :------- | :---------- | | name | string | | | | description | string | | | | user\_notes | string | | | | units | string | optional | | | client\_key | string | optional | | | calculated\_channel\_configuration | [CalculatedChannelConfiguration](#calculatedchannelconfiguration) | | | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | | ### CreateCalculatedChannelResponse | Field | Type | Label | Description | | :------------------- | :---------------------------------------------------------------------- | :------- | :---------- | | calculated\_channel | [CalculatedChannel](#calculatedchannel) | | | | inapplicable\_assets | [CalculatedChannelValidationResult](#calculatedchannelvalidationresult) | repeated | | ### GetCalculatedChannelDependentsRequest The request for a call to `CalculatedChannelService_GetCalculatedChannelDependents` to retrieve calculated channels that depend on a given calculated channel. | Field | Type | Label | Description | | :---------------------------------------------------------- | :----- | :---- | :---------- | | oneof calculated\_channel. calculated\_channel\_id | string | | | | oneof calculated\_channel. calculated\_channel\_version\_id | string | | | ### GetCalculatedChannelDependentsResponse The response of a call to `CalculatedChannelService_GetCalculatedChannelDependents`. | Field | Type | Label | Description | | :------------------- | :---------------------------------------- | :------- | :---------- | | calculated\_channels | [CalculatedChannel](#calculatedchannel) | repeated | | | rules | [sift.rules.v1.Rule](#sift-rules-v1-rule) | repeated | | ### GetCalculatedChannelRequest The request for a call to `CalculatedChannelService_GetCalculatedChannel` to retrieve the latest version of a calculated channel. If `calculated_channel_id` is provided then all other arguments will be ignored. The argument `calculated_channel_id` should not be used together with `client_key`. The `organization_id` argument is only required if using `client_key` and the user belongs to multiple organizations. | Field | Type | Label | Description | | :------------------------------- | :----- | :---- | :---------- | | calculated\_channel\_id | string | | | | client\_key | string | | | | organization\_id | string | | | | calculated\_channel\_version\_id | string | | | ### GetCalculatedChannelResponse | Field | Type | Label | Description | | :------------------ | :-------------------------------------- | :---- | :---------- | | calculated\_channel | [CalculatedChannel](#calculatedchannel) | | | ### GetCalculatedChannelVersionsRequest The request for a call to `CalculatedChannelService_GetCalculatedChannelVersions` to retrieve versions of calculated channels by their version IDs. | Field | Type | Label | Description | | :-------------------------------- | :----- | :------- | :---------- | | calculated\_channel\_version\_ids | string | repeated | | ### GetCalculatedChannelVersionsResponse The response of a call to `CalculatedChannelService_GetCalculatedChannelVersions`. | Field | Type | Label | Description | | :------------------- | :-------------------------------------- | :------- | :---------- | | calculated\_channels | [CalculatedChannel](#calculatedchannel) | repeated | | ### ListCalculatedChannelVersionsRequest The request for a call to `CalculatedChannelService_ListCalculatedChannelVersions` to retrieve versions of a particular calculated channel. If `calculated_channel_id` is provided then `client_key` is ignored. | Field | Type | Label | Description | | :---------------------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | calculated\_channel\_id | string | | | | client\_key | string | | | | page\_size | uint32 | | The maximum number of calculated channel versions to return. The service may return fewer than this value. If unspecified, at most 50 calculated channels will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListCalculatedChannelVersions` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListCalculatedChannelVersions` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `calculated_channel_id`, `organization_id`, `client_key`, `name`, `description`, `asset_id`, `asset_name`, `tag_id`, `tag_name`, `version`, `units`, `calculated_channel_version_id`, `created_date`, `modified_date`, `created_by_user_id`, `modified_by_user_id`, `is_archived`, and `archived_date`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | organization\_id | string | | This field is only required if your user belongs to multiple organizations. | | order\_by | string | | How to order the retrieved calculated channel versions. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `version`, `created_date`, and `modified_date`. If left empty, items are ordered by `version` in ascending order (oldest version first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date". | ### ListCalculatedChannelVersionsResponse The response of a call to `CalculatedChannelService_ListCalculatedChannelVersions`. | Field | Type | Label | Description | | :---------------------------- | :-------------------------------------- | :------- | :---------- | | calculated\_channel\_versions | [CalculatedChannel](#calculatedchannel) | repeated | | | next\_page\_token | string | | | ### ListCalculatedChannelsRequest The request for a call to `CalculatedChannelService_ListCalculatedChannels` to retrieve latest versions of calculated channels. | Field | Type | Label | Description | | :--------------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | page\_size | uint32 | | The maximum number of calculated channels to return. The service may return fewer than this value. If unspecified, at most 50 calculated channels will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListCalculatedChannels` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListCalculatedChannels` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `calculated_channel_id`, `organization_id`, `client_key`, `name`, `description`, `asset_id`, `asset_name`, `tag_id`, `tag_name`, `units`, `calculated_channel_version_id`, `created_date`, `modified_date`, `created_by_user_id`, `modified_by_user_id`, `is_archived`, and `archived_date`. Folder membership is filterable via the `folders` and `activeFolders` fields. Both contain the ids of the folders the calculated channel belongs to; `activeFolders` excludes archived folders. Use `"" in folders` to return calculated channels in the given folder, and `size(activeFolders) == 0` to return uncategorized calculated channels (calculated channels whose only memberships are in archived folders count as uncategorized). For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | organization\_id | string | | This field is only required if your user belongs to multiple organizations. | | order\_by | string | | How to order the retrieved calculated channels. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date` and `modified_date`. If left empty, items are ordered by `created_date` in descending order (newest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | ### ListCalculatedChannelsResponse The response of a call to `CalculatedChannelService_ListCalculatedChannels`. | Field | Type | Label | Description | | :------------------- | :-------------------------------------- | :------- | :---------- | | calculated\_channels | [CalculatedChannel](#calculatedchannel) | repeated | | | next\_page\_token | string | | | ### ListResolvedCalculatedChannelsRequest | Field | Type | Label | Description | | :---------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | asset\_id | string | | Assets or runs to get the resolved calculated channels for. At least one asset or run must be provided. | | run\_id | string | | | | page\_size | uint32 | | The maximum number of calculated channels to return. The service may return fewer than this value. If unspecified, at most 50 calculated channels will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListCalculatedChannels` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListCalculatedChannels` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `calculated_channel_id`, `organization_id`, `client_key`, `name`, `description`, `asset_id`, `asset_name`, `tag_id`, `tag_name`, `version`, `units`, `calculated_channel_version_id`, `created_date`, `modified_date`, `created_by_user_id`, `modified_by_user_id`, `is_archived`, and `archived_date`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved calculated channels. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date` and `modified_date`. If left empty, items are ordered by `created_date` in descending order (newest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | ### ListResolvedCalculatedChannelsResponse | Field | Type | Label | Description | | :------------------------------- | :---------------------------------------------------------- | :------- | :---------- | | calculated\_channel\_resolutions | [CalculatedChannelResolution](#calculatedchannelresolution) | repeated | | | next\_page\_token | string | | | ### ResolveCalculatedChannelRequest The request for a call to `CalculatedChannelService_ResolveCalculatedChannel` to get the all possible calculated channels. 1. If the calculated channel has a selection of assets and tags then those assets will be used as a base and then filtered down by the given assets and assets from the run. 2. If the calculated channel is enabled for all assets then: a) If the request has run and assets from the run will be used as a base and then filtered down by the given assets. b) If the request has run and no assets then those assets will be used. c) If the request has only assets then those assets will be used. The `organization_id` argument is only required if using `client_key` and the user belongs to multiple organizations. | Field | Type | Label | Description | | :------------------------------------------------------------ | :-------------------------------------------------------------------------------- | :------- | :-------------------------------------------------------------------------- | | oneof calculated\_channel. identifier | [sift.common.type.v1.ResourceIdentifier](#sift-common-type-v1-resourceidentifier) | | The calculated channel to resolve. | | oneof calculated\_channel. calculated\_channel\_configuration | [CalculatedChannelConfiguration](#calculatedchannelconfiguration) | | A configuration for the calculated channel to resolve. | | organization\_id | string | | This field is only required if your user belongs to multiple organizations. | | assets | [sift.common.type.v1.NamedResources](#sift-common-type-v1-namedresources) | | Assets to be included or filtered through. See above. | | run | [sift.common.type.v1.ResourceIdentifier](#sift-common-type-v1-resourceidentifier) | optional | Run to get assets to be included or filtered through. See above. | ### ResolveCalculatedChannelResponse The response of a call to `CalculatedChannelService_ResolveCalculatedChannel`. | Field | Type | Label | Description | | :---------------------- | :---------------------------------------------------------- | :------- | :----------------------------------------------------------- | | calculated\_channel\_id | string | optional | If provided in the request, the calculated channel resolved. | | resolved | [ResolvedCalculatedChannel](#resolvedcalculatedchannel) | repeated | All resolved calculated channels. | | unresolved | [UnresolvedCalculatedChannel](#unresolvedcalculatedchannel) | repeated | All assets with any issues in resolution. | ### ResolvedCalculatedChannel A specific calculated channel including the asset and exact channels to query. | Field | Type | Label | Description | | :------------------ | :----------------------------------------------------------------------------------------------- | :---- | :---------------------------------------------------- | | asset\_name | string | | The name of the specific asset that was resolved. | | expression\_request | [sift.calculated\_channels.v1.ExpressionRequest](#sift-calculated_channels-v1-expressionrequest) | | The expression resolved including channel references. | | output\_data\_type | [sift.common.type.v1.ChannelDataType](#sift-common-type-v1-channeldatatype) | | | | asset\_id | string | | | ### UnresolvedCalculatedChannel Any failure in resolution. | Field | Type | Label | Description | | :------------- | :----- | :---- | :---------------------------------------------------- | | asset\_name | string | | The name of the specific asset that was not resolved. | | error\_message | string | | | ### UpdateCalculatedChannelRequest The request for a call to `CalculatedChannelService_UpdateCalculatedChannel` to update a calculated channel. Updating a calculated channel creates a new version of the calculated channel, leaving the previous untouched. If no update is deemed necessary, then the the current version is returned. To archive calculated channel, specify `archived_date` in the `update mask` as well as a non-null value for `archived_date` in the `calculated_channel` object. To unarchive a calculated channel, specify `archived_date` in the `update mask` and a `null` value for `archived_date` in the `calculated_channel` object. | Field | Type | Label | Description | | :------------------ | :------------------------------------------------------ | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | calculated\_channel | [CalculatedChannel](#calculatedchannel) | | The calculated channel to update. | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The list of fields to be updated. The fields available to be updated are `name`, `description`, `units`, `metadata`, `query_configuration`, `archived_date`, `is_archived`, and `asset_configuration`. | | user\_notes | string | optional | Optional user notes to describe changes. | ### UpdateCalculatedChannelResponse The response of a call to `CalculatedChannelService_UpdateCalculatedChannel`. | Field | Type | Label | Description | | :------------------- | :---------------------------------------------------------------------- | :------- | :---------- | | calculated\_channel | [CalculatedChannel](#calculatedchannel) | | | | inapplicable\_assets | [CalculatedChannelValidationResult](#calculatedchannelvalidationresult) | repeated | | ## Enums *Allowed constant values used in message fields.* # campaigns Source: https://docs.siftstack.com/api/reference/protocol-buffers/campaigns sift/campaigns/v1/campaigns.proto ## Services *RPC methods exposed by this API.* ### CampaignService | Method | Request | Response | Description | | :------------------------- | :---------------------------------------------------------------------- | :------------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | GetCampaign | [GetCampaignRequest](#getcampaignrequest) | [GetCampaignResponse](#getcampaignresponse) | Retrieve a campaign. | | CreateCampaign | [CreateCampaignRequest](#createcampaignrequest) | [CreateCampaignResponse](#createcampaignresponse) | Create a campaign. | | ListCampaigns | [ListCampaignsRequest](#listcampaignsrequest) | [ListCampaignsResponse](#listcampaignsresponse) | List campaigns. | | UpdateCampaign | [UpdateCampaignRequest](#updatecampaignrequest) | [UpdateCampaignResponse](#updatecampaignresponse) | Updates an existing campaign using the list of fields specified in `update_mask`. | | ListCampaignAnnotations | [ListCampaignAnnotationsRequest](#listcampaignannotationsrequest) | [ListCampaignAnnotationsResponse](#listcampaignannotationsresponse) | List campaigns. | | GetCampaignReportSummaries | [GetCampaignReportSummariesRequest](#getcampaignreportsummariesrequest) | [GetCampaignReportSummariesResponse](#getcampaignreportsummariesresponse) | Returns per-campaign report summaries (annotation totals + rule classifications) in bulk. Each campaign maps to its list of CampaignReport entries with summary fields populated. Intended for use alongside ListCampaigns with skip\_report\_summaries=true. | ## Messages *Data models used across requests/responses.* ### Campaign | Field | Type | Label | Description | | :-------------------------- | :---------------------------------------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | campaign\_id | string | | | | organization\_id | string | | | | client\_key | string | optional | | | name | string | | | | description | string | optional | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | archived\_date | google.protobuf.Timestamp | | | | tags | [sift.tags.v1.TagRef](#sift-tags-v1-tagref) | repeated | | | reports | [CampaignReport](#campaignreport) | repeated | A campaign, at its core, is a list of reports | | created\_from\_campaign\_id | string | optional | If this campaign was created by duplicating another campaign, that other campaign will be referenced here | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | User-defined metadata for this campaign | | is\_archived | bool | | Whether the campaign. This is inferred from whether archived\_date is set. | | reports\_include\_summaries | bool | | Indicates whether the summary fields on CampaignReport (num\_annotations, num\_passed\_rules, num\_accepted\_rules, num\_failed\_rules, num\_open\_rules) are populated. When false, those fields should be ignored -- use GetCampaignReportSummaries to fetch the summary data separately. | ### CampaignReport A top-level summary of the report's rules is provided here so clients needn't aggregate this information themselves. | Field | Type | Label | Description | | :------------------- | :----- | :---- | :----------------------------------------------------------------------------------------------------------- | | report\_id | string | | Direct reference to the report. Set this on the client to tell the backend which report you're referring to. | | report\_name | string | | | | num\_annotations | uint32 | | How many annotations exist under the report's various rules. | | num\_passed\_rules | uint32 | | How many rules from this report were never triggered and generated NO annotations. | | num\_accepted\_rules | uint32 | | How many rules have annotations which are ALL marked as accepted. | | num\_failed\_rules | uint32 | | How many rules have ANY annotations which are marked as failed. | | num\_open\_rules | uint32 | | How many rules have annotations of which SOME are marked as open and NONE are marked as failed. | ### CampaignReports Wrapper for repeated CampaignReport used in map values (proto3 maps cannot directly contain repeated fields). | Field | Type | Label | Description | | :------ | :-------------------------------- | :------- | :---------- | | reports | [CampaignReport](#campaignreport) | repeated | | ### CreateCampaignFrom Campaigns can be created from a few different sources. | Field | Type | Label | Description | | :--------------------------------- | :---------------------------------------------------------------------------------- | :---- | :----------------------------------------------------------------------------------------- | | oneof initializer. reports | [sift.common.type.v1.ResourceIdentifiers](#sift-common-type-v1-resourceidentifiers) | | Create a campaign directly from a set of reports | | oneof initializer. runs | [sift.common.type.v1.ResourceIdentifiers](#sift-common-type-v1-resourceidentifiers) | | Create a campaign from a set of runs by collecting all the reports generated by those runs | | oneof initializer. other\_campaign | [sift.common.type.v1.ResourceIdentifier](#sift-common-type-v1-resourceidentifier) | | Duplicate another campaign | ### CreateCampaignRequest The request of a call to `CampaignService_CreateCampaign` to create a campaign. | Field | Type | Label | Description | | :--------------- | :------------------------------------------------------------------------ | :------- | :--------------------------------------------------------------------------------------------------- | | name | string | | The descriptive display name of the created campaign | | description | string | optional | A custom description for the campaign | | tags | [sift.common.type.v1.NamedResources](#sift-common-type-v1-namedresources) | | Tags to be applied to the new campaign | | organization\_id | string | | `organization_id` is only required if your user belongs to multiple organizations | | client\_key | string | optional | User-specified unique identifier. | | create\_from | [CreateCampaignFrom](#createcampaignfrom) | | Initialize the campaign, or leave this field empty to create an empty campaign to be populated later | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | User-defined metadata for this campaign | ### CreateCampaignResponse The response of a call to `CampaignService_CreateCampaign` to create a campaign. | Field | Type | Label | Description | | :------- | :-------------------- | :---- | :---------- | | campaign | [Campaign](#campaign) | | | ### GetCampaignReportSummariesRequest | Field | Type | Label | Description | | :--------------- | :----- | :------- | :-------------------------------------------------------------------------- | | campaign\_ids | string | repeated | | | organization\_id | string | | This field is only required if your user belongs to multiple organizations. | ### GetCampaignReportSummariesResponse | Field | Type | Label | Description | | :-------------------------- | :------------------------------------------------------------------------------------------------------------------------------ | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------- | | summaries\_by\_campaign\_id | [GetCampaignReportSummariesResponse.SummariesByCampaignIdEntry](#getcampaignreportsummariesresponse-summariesbycampaignidentry) | repeated | Keyed by campaign\_id. Each value contains the full list of CampaignReport entries for that campaign with summary fields (num\_\*) populated. | ### GetCampaignReportSummariesResponse.SummariesByCampaignIdEntry | Field | Type | Label | Description | | :---- | :---------------------------------- | :---- | :---------- | | key | string | | | | value | [CampaignReports](#campaignreports) | | | ### GetCampaignRequest The request for a call to `CampaignService_GetCampaign` to retrieve a campaign. If `campaign_id` is provided then all other arguments will be ignored. The `organization_id` argument is only required if using `client_key` and the user belongs to multiple organizations. | Field | Type | Label | Description | | :---------------------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | campaign\_id | string | | | | client\_key | string | | | | organization\_id | string | | | | skip\_report\_summaries | bool | | If `true`, the response will omit the summary fields on the campaign's reports and set reports\_include\_summaries to false on the Campaign message. Reports will still be included with report\_id and report\_name populated. This significantly improves response times for campaigns with many reports. Defaults to `false`. | ### GetCampaignResponse The response of a call to `CampaignService_GetCampaign` to retrieve a campaign. | Field | Type | Label | Description | | :------- | :-------------------- | :---- | :---------- | | campaign | [Campaign](#campaign) | | | ### ListCampaignAnnotationsRequest | Field | Type | Label | Description | | :----------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | campaign\_id | string | | | | page\_size | uint32 | | The maximum number of annotations to return. The service may return fewer than this value. If unspecified, at most 50 annotations will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListAnnotations` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListAnnotations` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `annotation_id`, `start_time`, `end_time`, `created_date`, `modified_date`, `run_id`, `name`, `description`, `state`, `created_by_user_id`, `created_by_rule_condition_version_id`, `annotation_type`, `tag_name`, `report_id`, `asset_id`, `asset_name`, `pending`, `assignee`, and `metadata`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved annotations. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date`, `modified_date`, `start_time`, and `end_time`. If left empty, items are ordered by `created_date` in ascending order (oldest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | ### ListCampaignAnnotationsResponse | Field | Type | Label | Description | | :---------------- | :---------------------------------------------------------------- | :------- | :---------- | | annotations | [sift.annotations.v1.Annotation](#sift-annotations-v1-annotation) | repeated | | | next\_page\_token | string | | | ### ListCampaignsRequest The request for a call to `CampaignService_ListCampaigns` to retrieve campaigns. | Field | Type | Label | Description | | :---------------------- | :----- | :---- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of campaigns to return. The service may return fewer than this value. If unspecified, at most 50 campaigns will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListCampaigns` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListCampaigns` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are: `created_by_user_id`, `tag_id`, `tag_name`, `report_id`, `report_name`, `campaign_id`, `client_key`, `description`, `run_id`, `name`, `is_archived`, and `metadata`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). For more information about the fields used for filtering, please refer to this definition. Optional. | | organization\_id | string | | This field is only required if your user belongs to multiple organizations. | | include\_archived | bool | | If `true` then archived campaigns will be included in the query. Defaults to `false`. | | order\_by | string | | How to order the retrieved campaigns. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `name`, `created_date` and `modified_date`. If left empty, items are ordered by `created_date` in descending order (newest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | | skip\_report\_summaries | bool | | If `true`, the response will omit the summary fields on each campaign's reports and set reports\_include\_summaries to false on the Campaign message. Reports will still be included with report\_id and report\_name populated. This significantly improves response times for campaigns with many reports. Defaults to `false`. | ### ListCampaignsResponse The response of a call to `CampaignService_ListCampaignsResponse`. | Field | Type | Label | Description | | :---------------- | :-------------------- | :------- | :---------- | | campaigns | [Campaign](#campaign) | repeated | | | next\_page\_token | string | | | ### UpdateCampaignRequest The request for a call to `CampaignService_UpdateCampaign` to update a campaign. When updating tags or rules, the update will perform a full replace. Additionally, when updating rules, only the rule ID or the rule client key is required, but it is okay to provide both. If some rules contain only client keys and others only rule IDs, they will be consolidated. | Field | Type | Label | Description | | :----------- | :------------------------------------------------------ | :---- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | campaign | [Campaign](#campaign) | | The campaign to update. | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The list of fields to be updated. The fields available to be updated are `name`, `archived_date`, `is_archived`, `description`, `tags`, `reports`, and `metadata`. | ### UpdateCampaignResponse The response of a call to `CampaignService_UpdateCampaign`. | Field | Type | Label | Description | | :------- | :-------------------- | :---- | :---------- | | campaign | [Campaign](#campaign) | | | ## Enums *Allowed constant values used in message fields.* # canvas Source: https://docs.siftstack.com/api/reference/protocol-buffers/canvas sift/canvas/v1/canvas.proto ## Services *RPC methods exposed by this API.* ## Messages *Data models used across requests/responses.* ## Enums *Allowed constant values used in message fields.* ### CanvasCellExecutionStatus Status of a single canvas cell execution. Also used as the status of the parent CanvasExecution: the parent rolls up its cells' statuses into a single value (e.g. any AUTO\_FAILED cell yields an AUTO\_FAILED execution). | Name | Number | Description | | :--------------------------------------------------- | :----- | :---------- | | CANVAS\_CELL\_EXECUTION\_STATUS\_UNSPECIFIED | 0 | | | CANVAS\_CELL\_EXECUTION\_STATUS\_IN\_PROGRESS | 1 | | | CANVAS\_CELL\_EXECUTION\_STATUS\_AUTO\_PASSED | 2 | | | CANVAS\_CELL\_EXECUTION\_STATUS\_AUTO\_FAILED | 3 | | | CANVAS\_CELL\_EXECUTION\_STATUS\_MANUAL\_PASSED | 4 | | | CANVAS\_CELL\_EXECUTION\_STATUS\_MANUAL\_FAILED | 5 | | | CANVAS\_CELL\_EXECUTION\_STATUS\_ERROR | 6 | | | CANVAS\_CELL\_EXECUTION\_STATUS\_SKIPPED | 7 | | | CANVAS\_CELL\_EXECUTION\_STATUS\_OPEN | 8 | | | CANVAS\_CELL\_EXECUTION\_STATUS\_MANUALLY\_CANCELLED | 9 | | # channel_bit_field_element Source: https://docs.siftstack.com/api/reference/protocol-buffers/channel_bit_field_element sift/common/type/v1/channel_bit_field_element.proto ## Services *RPC methods exposed by this API.* ## Messages *Data models used across requests/responses.* ### ChannelBitFieldElement | Field | Type | Label | Description | | :--------- | :----- | :---- | :-------------------------------------------------------------------- | | name | string | | | | index | int32 | | The index of this element's first bit in the logical bit field array. | | bit\_count | uint32 | | | ## Enums *Allowed constant values used in message fields.* # channel_config Source: https://docs.siftstack.com/api/reference/protocol-buffers/channel_config sift/common/type/v1/channel_config.proto ## Services *RPC methods exposed by this API.* ## Messages *Data models used across requests/responses.* ### ChannelConfig | Field | Type | Label | Description | | :------------------- | :---------------------------------------------------------------- | :------- | :---------- | | name | string | | | | units | string | | | | description | string | | | | data\_type | [ChannelDataType](#channeldatatype) | | | | enum\_types | [ChannelEnumType](#channelenumtype) | repeated | | | bit\_field\_elements | [ChannelBitFieldElement](#channelbitfieldelement) | repeated | | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | | ## Enums *Allowed constant values used in message fields.* # channel_data_type Source: https://docs.siftstack.com/api/reference/protocol-buffers/channel_data_type sift/common/type/v1/channel_data_type.proto ## Services *RPC methods exposed by this API.* ## Messages *Data models used across requests/responses.* ## Enums *Allowed constant values used in message fields.* ### ChannelDataType | Name | Number | Description | | :------------------------------- | :----- | :-------------- | | CHANNEL\_DATA\_TYPE\_UNSPECIFIED | 0 | **Deprecated.** | | CHANNEL\_DATA\_TYPE\_DOUBLE | 1 | | | CHANNEL\_DATA\_TYPE\_STRING | 2 | | | CHANNEL\_DATA\_TYPE\_ENUM | 3 | | | CHANNEL\_DATA\_TYPE\_BIT\_FIELD | 4 | | | CHANNEL\_DATA\_TYPE\_BOOL | 5 | | | CHANNEL\_DATA\_TYPE\_FLOAT | 6 | | | CHANNEL\_DATA\_TYPE\_INT\_32 | 7 | | | CHANNEL\_DATA\_TYPE\_UINT\_32 | 8 | | | CHANNEL\_DATA\_TYPE\_INT\_64 | 9 | | | CHANNEL\_DATA\_TYPE\_UINT\_64 | 10 | | | CHANNEL\_DATA\_TYPE\_BYTES | 11 | | # channel_enum_type Source: https://docs.siftstack.com/api/reference/protocol-buffers/channel_enum_type sift/common/type/v1/channel_enum_type.proto ## Services *RPC methods exposed by this API.* ## Messages *Data models used across requests/responses.* ### ChannelEnumType | Field | Type | Label | Description | | :--------- | :----- | :---- | :---------- | | name | string | | | | key | uint32 | | | | is\_signed | bool | | | ## Enums *Allowed constant values used in message fields.* # channel_parsing_options Source: https://docs.siftstack.com/api/reference/protocol-buffers/channel_parsing_options sift/protobuf_descriptors/v2/channel_parsing_options.proto These are message and field options that can be used when ingesting protobuf messages. These can be applied to protobuf fields and messages before compiling and uploading the descriptor set. * [File-level Extensions](#sift_protobuf_descriptors_v2_channel_parsing_options-proto-extensions) ## Services *RPC methods exposed by this API.* ## Messages *Data models used across requests/responses.* ### TagSource Message representing a tag source Setting either of these values indicates that the field is a tag source and the value can be applied to allowed tag\_targets. Tag sources apply only to the nearest ancestor (if any) and do not propagate to ancestors that are lists or maps or beyond. They can apply to both ancestor and sibling fields. | Field | Type | Label | Description | | :------------------- | :------------------------------ | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | allowed\_tag\_target | [TagTargetType](#tagtargettype) | optional | Indicates which tag\_target relationships are allowed to have this tag. If set to ANCESTOR\_TARGETS, sibling tag\_targets will not have this value. If set to SIBLING\_TARGETS, it will not apply to tag\_targets that are ancestors. | | tag\_name | string | optional | The name of the tag. It defaults to the field name but can be overridden here. | ### TagTarget Message representing a tag target | Field | Type | Label | Description | | :------------------- | :------------------------------ | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | allowed\_tag\_source | [TagSourceType](#tagsourcetype) | optional | Setting this value indicates the allowed sources for tag values. If set to SIBLING\_SOURCES, tag\_sources from descendant proto fields will not be applied. If set to DESCENDANT\_SOURCES, sibling tag\_sources will not be applied. | ## Enums *Allowed constant values used in message fields.* ### ArrayIndexOverrideType Enum for the source and destination of an array index override | Name | Number | Description | | :------------------------------------ | :----- | :---------------------------------------------------------------------------------------------------------- | | ARRAY\_INDEX\_OVERRIDE\_UNSPECIFIED | 0 | Default value, will be ignored | | ARRAY\_INDEX\_OVERRIDE\_TARGET | 1 | Array Index will be replaced on fields with this type specified | | ARRAY\_INDEX\_OVERRIDE\_SOURCE | 2 | Array Index will be sourced from fields with this type specified | | ARRAY\_INDEX\_OVERRIDE\_REMOVE\_INDEX | 3 | Array Index will be removed from fields with this type specified | | ARRAY\_INDEX\_OVERRIDE\_ENUM | 4 | Array Index will be replaced with the enum name specified by the display\_override\_enum value on the field | ### BytesDecodingType Enum for how to decode bytes fields | Name | Number | Description | | :--------------------------------- | :----- | :----------------------------------------- | | BYTES\_DECODING\_TYPE\_UNSPECIFIED | 0 | Default value, will be stored as raw bytes | | BYTES\_DECODING\_TYPE\_UTF8 | 1 | Decode bytes as UTF-8 | ### MapKeyOverrideType Enum for the source and destination of a map key override | Name | Number | Description | | :------------------------------ | :----- | :------------------------------------------------------------------------------------------------------ | | MAP\_KEY\_OVERRIDE\_UNSPECIFIED | 0 | Default value, will be ignored | | MAP\_KEY\_OVERRIDE\_TARGET | 1 | Map key will be replaced on fields with this type specified | | MAP\_KEY\_OVERRIDE\_SOURCE | 2 | Map key will be sourced from fields with this type specified | | MAP\_KEY\_OVERRIDE\_REMOVE\_KEY | 3 | Map key will be removed from fields with this type specified | | MAP\_KEY\_OVERRIDE\_ENUM | 4 | Map key will be replaced with the enum name specified by the display\_override\_enum value on the field | ### TagSourceType Enum for different types of tag sources | Name | Number | Description | | :-------------------------------- | :----- | :---------------------------------------------------------- | | DESCENDANT\_SOURCES | 0 | Tags can be sourced from descendant fields | | SIBLING\_SOURCES | 1 | Tags can be sourced from sibling fields | | DESCENDANT\_AND\_SIBLING\_SOURCES | 2 | Tags can be sourced from both descendant and sibling fields | ### TagTargetType Enum for different types of tag targets | Name | Number | Description | | :------------------------------ | :----- | :------------------------------------------------------ | | ANCESTOR\_TARGETS | 0 | Tags can be applied to ancestor fields | | SIBLING\_TARGETS | 1 | Tags can be applied to sibling fields | | ANCESTOR\_AND\_SIBLING\_TARGETS | 2 | Tags can be applied to both ancestor and sibling fields | ## File-level Extensions *File-wide options and annotations.* | Extension | Type | Base | Number | Description | | :--------------------------- | :--------------------- | :------------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | array\_index\_override\_type | ArrayIndexOverrideType | .google.protobuf.FieldOptions | 50009 | Adding the array\_index\_override\_type FieldOption to a repeated type field with the `ARRAY_INDEX_OVERRIDE_TARGET` type indicates that this field can have the array index replaced in the display name by a descendant field. Adding this to a primitive type field with the `ARRAY_INDEX_OVERRIDE_SOURCE` type indicates that this field is the replacement value for an ancestor array's index display. Note that sources within nested arrays will not apply to ancestor arrays that contain those arrays. This tag will be ignored if the field is not an array or if there are no `ARRAY_INDEX_OVERRIDE_SOURCE` fields that apply. If multiple apply then the first override will be applied and an error will be logged. | | bytes\_decoding\_type | BytesDecodingType | .google.protobuf.FieldOptions | 50006 | Adding the bytes\_decoding\_type FieldOption to a bytes field indicates how the bytes should be decoded If not set, the bytes fields will be ignored and an error will be logged. | | description | string | .google.protobuf.FieldOptions | 50002 | Adding the description FieldOption to a field sets the description for the channel in the chart | | display\_override\_enum | string | .google.protobuf.FieldOptions | 50008 | Adding the display\_override\_enum FieldOption to a field with that has map\_key\_override\_type set to MAP\_KEY\_OVERRIDE\_ENUM will look up the enum value in the enum referenced by this field and use that to look up the enum value by number and replace it with the enum value name. | | ignore\_field | bool | .google.protobuf.FieldOptions | 50007 | Adding the ignore\_field FieldOption with a value of true will cause the field to be ignored when ingesting the proto | | map\_key\_override\_type | MapKeyOverrideType | .google.protobuf.FieldOptions | 50005 | Adding the map\_key\_override\_type FieldOption to a map type field with the `MAP_KEY_OVERRIDE_TARGET` type indicates that this field can have the map key replaced in the display name by a descendant field. Adding this to a primitive type field with the `MAP_KEY_OVERRIDE_SOURCE` indicates that this field is the replacement value for an ancestor map's key display. Note that sources within arrays will not apply to ancestor maps that contain those arrays. This tag will be ignored if the field is not a map or if there are no map\_key\_override\_sources that apply. If multiple apply then the first override will be applied and an error will be logged. | | store\_message\_as\_bytes | bool | .google.protobuf.FieldOptions | 50010 | Adding the store\_message\_as\_bytes FieldOption to a message field indicates that the message should be stored as serialized protobuf. When enabled, instead of creating channels for each field in the message, a single bytes channel will be created for the entire message. This tag will cause a validation error if the field is not a message type. | | tag\_source | TagSource | .google.protobuf.FieldOptions | 50004 | Adding the tag\_source FieldOption allows the value of the annotated field to be added to applicable fields that are annotated with tag\_target. These fields can be either ancestor fields or sibling fields, depending on their respective fields' allowed\_tag\_source and allowed\_tag\_target values. | | tag\_target | TagTarget | .google.protobuf.FieldOptions | 50003 | Adding the tag\_target FieldOption indicates that this field can have tag values appended to the field name. The tag values will come from descendant or sibling fields in the proto path that have the tag\_source FieldOption applied. | | units | string | .google.protobuf.FieldOptions | 50001 | Adding the units FieldOption to a field sets the units displayed on the channel when charted | | message\_is\_tag\_target | bool | .google.protobuf.MessageOptions | 50001 | The message\_is\_tag\_target option indicates that the message will allow its fields to have tags added to them. This option only accepts descendant sources. It can be helpful to annotate top-level messages with tags from deeper in the proto path. | # channel_schemas Source: https://docs.siftstack.com/api/reference/protocol-buffers/channel_schemas sift/channel_schemas/v2/channel_schemas.proto ## Services *RPC methods exposed by this API.* ### ChannelSchemaService | Method | Request | Response | Description | | :------------------------ | :-------------------------------------------------------------------- | :---------------------------------------------------------------------- | :-------------------------------- | | CreateChannelSchema | [CreateChannelSchemaRequest](#createchannelschemarequest) | [CreateChannelSchemaResponse](#createchannelschemaresponse) | Create a channel schema | | BatchCreateChannelSchemas | [BatchCreateChannelSchemasRequest](#batchcreatechannelschemasrequest) | [BatchCreateChannelSchemasResponse](#batchcreatechannelschemasresponse) | Create a batch of channel schemas | ## Messages *Data models used across requests/responses.* ### BatchCreateChannelSchemasRequest The request for a call to `ChannelSchemaService_BatchCreateChannelSchemas`. | Field | Type | Label | Description | | :---------- | :-------------------------------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | requests | [CreateChannelSchemaRequest](#createchannelschemarequest) | repeated | Limit of 1000 channels schemas per batch | | asset\_name | string | | The asset to which the channel schemas belong (case-insensitive). If this field, and any of the child requests specify an asset, the assets must match. | ### BatchCreateChannelSchemasResponse The response of a call to `ChannelSchemaService_BatchCreateChannelSchemas`. *This message has no fields.* ### CreateChannelSchemaRequest The request for a call to `ChannelSchemaService_CreateChannelSchema`. | Field | Type | Label | Description | | :------------------- | :---------------------------------------------------------------------------------------- | :------- | :---------------------------------------- | | channel | string | | | | unit | string | | | | data\_type | [sift.common.type.v1.ChannelDataType](#sift-common-type-v1-channeldatatype) | | | | enum\_types | [sift.common.type.v1.ChannelEnumType](#sift-common-type-v1-channelenumtype) | repeated | | | bit\_field\_elements | [sift.common.type.v1.ChannelBitFieldElement](#sift-common-type-v1-channelbitfieldelement) | repeated | | | asset\_name | string | | The name of the asset (case-insensitive). | ### CreateChannelSchemaResponse The response of a call to `ChannelSchemaService_CreateChannelSchema`. *This message has no fields.* ## Enums *Allowed constant values used in message fields.* # channels Source: https://docs.siftstack.com/api/reference/protocol-buffers/channels sift/channels/v3/channels.proto ## Services *RPC methods exposed by this API.* ### ChannelService | Method | Request | Response | Description | | :--------------------- | :-------------------------------------------------------------- | :---------------------------------------------------------------- | :--------------------------------------------------- | | GetChannel | [GetChannelRequest](#getchannelrequest) | [GetChannelResponse](#getchannelresponse) | Retrieve a channel | | ListChannels | [ListChannelsRequest](#listchannelsrequest) | [ListChannelsResponse](#listchannelsresponse) | Retrieve channels using an optional filter. | | UpdateChannel | [UpdateChannelRequest](#updatechannelrequest) | [UpdateChannelResponse](#updatechannelresponse) | Update a channel | | BatchArchiveChannels | [BatchArchiveChannelsRequest](#batcharchivechannelsrequest) | [BatchArchiveChannelsResponse](#batcharchivechannelsresponse) | Batch archives channels by setting active to false. | | BatchUnarchiveChannels | [BatchUnarchiveChannelsRequest](#batchunarchivechannelsrequest) | [BatchUnarchiveChannelsResponse](#batchunarchivechannelsresponse) | Batch unarchives channels by setting active to true. | ## Messages *Data models used across requests/responses.* ### BatchArchiveChannelsRequest The request for a call to ChannelService\_BatchArchiveChannels. | Field | Type | Label | Description | | :----------- | :----- | :------- | :---------- | | channel\_ids | string | repeated | | ### BatchArchiveChannelsResponse The result of a call to ChannelService\_BatchArchiveChannels. *This message has no fields.* ### BatchUnarchiveChannelsRequest The request for a call to ChannelService\_BatchUnarchiveChannels. | Field | Type | Label | Description | | :----------- | :----- | :------- | :---------- | | channel\_ids | string | repeated | | ### BatchUnarchiveChannelsResponse The result of a call to ChannelService\_BatchUnarchiveChannels. *This message has no fields.* ### Channel | Field | Type | Label | Description | | :--------------------- | :---------------------------------------------------------------------------------------- | :------- | :---------------------------- | | channel\_id | string | | | | name | string | | The full name of the channel. | | asset\_id | string | | | | description | string | | | | unit\_id | string | | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | data\_type | [sift.common.type.v1.ChannelDataType](#sift-common-type-v1-channeldatatype) | | | | enum\_types | [sift.common.type.v1.ChannelEnumType](#sift-common-type-v1-channelenumtype) | repeated | | | bit\_field\_elements | [sift.common.type.v1.ChannelBitFieldElement](#sift-common-type-v1-channelbitfieldelement) | repeated | | | display\_description | string | | | | display\_unit\_id | string | | | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | | | active | bool | | | ### FilterChannel | Field | Type | Label | Description | | :------------------- | :---------------------------------------------------------------------------------------- | :------- | :---------- | | channel\_id | string | | | | name | string | | | | organization\_id | string | | | | asset\_id | string | | | | asset\_name | string | | | | description | string | | | | display\_description | string | | | | unit\_id | string | | | | display\_unit\_id | string | | | | unit | string | | | | display\_unit | string | | | | data\_type | [sift.common.type.v1.ChannelDataType](#sift-common-type-v1-channeldatatype) | | | | enum\_types | [sift.common.type.v1.ChannelEnumType](#sift-common-type-v1-channelenumtype) | repeated | | | bit\_field\_elements | [sift.common.type.v1.ChannelBitFieldElement](#sift-common-type-v1-channelbitfieldelement) | repeated | | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | | ### FilterChannelsRequest The request for a call to ChannelService\_FilterChannels. | Field | Type | Label | Description | | :-------------------------- | :-------------------------------------------------------------------------- | :------- | :------------------------------------------------------------------------------------- | | page\_size | uint32 | | | | page\_token | string | | | | search\_term | string | | The search term to match against channel names, components and descriptions. Optional. | | is\_search\_case\_sensitive | bool | | If true, the search term is case sensitive. Optional, default false. | | is\_search\_regexp | bool | | If true, the search term is treated as a regular expression. Optional, default false. | | asset\_ids | string | repeated | If provided, only channels matching these asset\_ids are returned. Optional | | run\_ids | string | repeated | Only channels for these runs are returned. Optional | | channel\_ids | string | repeated | If provided, only channels matching these channel\_ids are returned. Optional | | asset\_tag\_ids | string | repeated | If provided, only channels with assets with these tag\_ids are returned. Optional | | data\_types | [sift.common.type.v1.ChannelDataType](#sift-common-type-v1-channeldatatype) | repeated | If provide, only channels with these data types are returned. Optional. | | metadata\_keys | string | repeated | If provided, only channels with this metadata are returned. Optional. | | metadata\_values | string | repeated | | ### FilterChannelsResponse The result of a call to ChannelService\_FilterChannels. | Field | Type | Label | Description | | :---------------- | :------------------------------ | :------- | :---------- | | channels | [FilterChannel](#filterchannel) | repeated | | | next\_page\_token | string | | | ### GetChannelRequest The request for a call to `ChannelService_GetChannel`. | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------- | | channel\_id | string | | | ### GetChannelResponse The response of a call to `ChannelService_GetChannel`. | Field | Type | Label | Description | | :------ | :------------------ | :---- | :---------- | | channel | [Channel](#channel) | | | ### ListChannelsRequest The request for a call to `ChannelService_ListChannels` to retrieve channels. | Field | Type | Label | Description | | :---------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of channels to return. The service may return fewer than this value. If unspecified, at most 50 channels will be returned. The maximum value is 10,000; values above 10,000 will be coerced to 10,000. Optional. | | page\_token | string | | A page token, received from a previous `ListChannels` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListChannels` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `channel_id`, `asset_id`, `name`, `description` `run_id`, `run_name`, `run_client_key`, `created_date`, `modified_date`, `created_by_user_id`, and `modified_by_user_id`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved channels. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `name`, `created_date` and `modified_date`, `active`. If left empty, items are ordered by `created_date` in ascending order (oldest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | ### ListChannelsResponse The result of a call to ChannelService\_ListChannels. | Field | Type | Label | Description | | :---------------- | :------------------ | :------- | :---------- | | channels | [Channel](#channel) | repeated | | | next\_page\_token | string | | | ### UpdateChannelRequest The request for a call to ChannelService\_UpdateChannel. | Field | Type | Label | Description | | :----------- | :------------------------------------------------------ | :---- | :----------------------------------------------------------------------------------------------------------------------------------------- | | channel | [Channel](#channel) | | | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The list of fields to be updated. The fields available to be updated are `display_description`, `display_units`, `metadata`, and `active`. | ### UpdateChannelResponse The result of a call to ChannelService\_UpdateChannel. | Field | Type | Label | Description | | :------ | :------------------ | :---- | :---------- | | channel | [Channel](#channel) | | | ## Enums *Allowed constant values used in message fields.* # comment Source: https://docs.siftstack.com/api/reference/protocol-buffers/comment sift/comment/v1/comment.proto ## Services *RPC methods exposed by this API.* ### CommentService | Method | Request | Response | Description | | :------------ | :-------------------------------------------- | :---------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------- | | CreateComment | [CreateCommentRequest](#createcommentrequest) | [CreateCommentResponse](#createcommentresponse) | Creates a comment on a resource. | | ListComments | [ListCommentsRequest](#listcommentsrequest) | [ListCommentsResponse](#listcommentsresponse) | Retrieves comments using an optional filter. Commonly used to bulk-fetch comments for a set of resource IDs of a given entity type. | | UpdateComment | [UpdateCommentRequest](#updatecommentrequest) | [UpdateCommentResponse](#updatecommentresponse) | Updates the body of an existing comment. | | DeleteComment | [DeleteCommentRequest](#deletecommentrequest) | [DeleteCommentResponse](#deletecommentresponse) | Deletes a comment. | ## Messages *Data models used across requests/responses.* ### Comment A single comment attached to a resource. | Field | Type | Label | Description | | :---------------------- | :---------------------------------------- | :------- | :-------------------------------------------------------------------------------------- | | comment\_id | string | | | | resource\_id | string | | The ID of the resource the comment is attached to (e.g. a canvas\_cell\_execution\_id). | | entity\_type | [CommentEntityType](#commententitytype) | | The kind of resource `resource_id` refers to. | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | created\_by\_user\_name | string | | | | body | [CommentBodyElement](#commentbodyelement) | repeated | The rich-text body of the comment. | ### CommentBodyElement A single element of a comment body. Either plain text or a user mention. | Field | Type | Label | Description | | :------------ | :------------------------------------------------ | :---- | :------------------------------------- | | type | [CommentBodyElementType](#commentbodyelementtype) | | | | text | string | | Only set when `type` is TEXT. | | user\_mention | [CommentUserMention](#commentusermention) | | Only set when `type` is USER\_MENTION. | ### CommentUserMention | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------- | | user\_id | string | | | | user\_email | string | | | ### CreateCommentRequest The request for a call to `CommentService_CreateComment`. | Field | Type | Label | Description | | :----------- | :---------------------------------------- | :------- | :----------------------------------------------- | | resource\_id | string | | The ID of the resource to attach the comment to. | | entity\_type | [CommentEntityType](#commententitytype) | | The kind of resource `resource_id` refers to. | | body | [CommentBodyElement](#commentbodyelement) | repeated | The rich-text body of the new comment. | ### CreateCommentResponse The response of a call to `CommentService_CreateComment`. | Field | Type | Label | Description | | :------ | :------------------ | :---- | :---------- | | comment | [Comment](#comment) | | | ### DeleteCommentRequest The request for a call to `CommentService_DeleteComment`. | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------- | | comment\_id | string | | | ### DeleteCommentResponse The response of a call to `CommentService_DeleteComment`. *This message has no fields.* ### ListCommentsRequest The request for a call to `CommentService_ListComments`. Commonly invoked with a CEL `filter` of the form `entity_type == "CANVAS_CELL_EXECUTION" && resource_id in ["", ...]` to bulk-fetch comments for a set of resources. | Field | Type | Label | Description | | :---------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | page\_size | uint32 | | The maximum number of comments to return. Defaults to 50, max 1000. | | page\_token | string | | A page token, received from a previous `ListComments` call. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `comment_id`, `resource_id`, `entity_type`, `created_by_user_id`, `created_date`, and `modified_date`. | | order\_by | string | | How to order the retrieved comments. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date` and `modified_date`. Defaults to `created_date` ascending (oldest-first). | ### ListCommentsResponse The response of a call to `CommentService_ListComments`. | Field | Type | Label | Description | | :---------------- | :------------------ | :------- | :---------- | | comments | [Comment](#comment) | repeated | | | next\_page\_token | string | | | ### UpdateCommentRequest The request for a call to `CommentService_UpdateComment`. | Field | Type | Label | Description | | :----------- | :------------------ | :---- | :------------------------------------------------------------------ | | comment | [Comment](#comment) | | | | update\_mask | string | | Comma-separated list of fields to update. Only `body` is supported. | ### UpdateCommentResponse The response of a call to `CommentService_UpdateComment`. | Field | Type | Label | Description | | :------ | :------------------ | :---- | :---------- | | comment | [Comment](#comment) | | | ## Enums *Allowed constant values used in message fields.* ### CommentBodyElementType | Name | Number | Description | | :------------------------------------------ | :----- | :---------- | | COMMENT\_BODY\_ELEMENT\_TYPE\_UNSPECIFIED | 0 | | | COMMENT\_BODY\_ELEMENT\_TYPE\_TEXT | 1 | | | COMMENT\_BODY\_ELEMENT\_TYPE\_USER\_MENTION | 2 | | ### CommentEntityType The type of resource a comment is attached to. Designed to be extended over time. | Name | Number | Description | | :--------------------------------------------- | :----- | :---------- | | COMMENT\_ENTITY\_TYPE\_UNSPECIFIED | 0 | | | COMMENT\_ENTITY\_TYPE\_CANVAS\_CELL\_EXECUTION | 1 | | # data Source: https://docs.siftstack.com/api/reference/protocol-buffers/data sift/data/v2/data.proto ## Services *RPC methods exposed by this API.* ### DataService | Method | Request | Response | Description | | :------ | :-------------------------------- | :---------------------------------- | :---------- | | GetData | [GetDataRequest](#getdatarequest) | [GetDataResponse](#getdataresponse) | Query data | ## Messages *Data models used across requests/responses.* ### BitFieldElementValues | Field | Type | Label | Description | | :----- | :------------------------------ | :------- | :---------- | | name | string | | | | values | [BitFieldValue](#bitfieldvalue) | repeated | | ### BitFieldValue | Field | Type | Label | Description | | :-------- | :------------------------ | :---- | :---------- | | timestamp | google.protobuf.Timestamp | | | | value | uint32 | | | ### BitFieldValues | Field | Type | Label | Description | | :------- | :---------------------------------------------- | :------- | :---------- | | metadata | [Metadata](#metadata) | | | | values | [BitFieldElementValues](#bitfieldelementvalues) | repeated | | ### BoolValue | Field | Type | Label | Description | | :-------- | :------------------------ | :---- | :---------- | | timestamp | google.protobuf.Timestamp | | | | value | bool | | | ### BoolValues | Field | Type | Label | Description | | :------- | :-------------------------------------------------------- | :------- | :---------- | | metadata | [Metadata](#metadata) | | | | values | [BoolValue](#boolvalue) | repeated | | | extras | [DimensionIndividualWrapper](#dimensionindividualwrapper) | repeated | | ### BytesValue | Field | Type | Label | Description | | :-------- | :------------------------ | :---- | :---------- | | timestamp | google.protobuf.Timestamp | | | | value | bytes | | | ### BytesValues | Field | Type | Label | Description | | :------- | :-------------------------------------------------------- | :------- | :---------- | | metadata | [Metadata](#metadata) | | | | values | [BytesValue](#bytesvalue) | repeated | | | extras | [DimensionIndividualWrapper](#dimensionindividualwrapper) | repeated | | ### CalculatedChannelQuery | Field | Type | Label | Description | | :----------------- | :----------------------------------------------------------------------------------------------- | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | channel\_key | string | | | | expression | [sift.calculated\_channels.v1.ExpressionRequest](#sift-calculated_channels-v1-expressionrequest) | | | | run\_id | string | optional | Optional. If set, only data for the specified run is returned If set to the empty string, only non-run data is returned. If unset, all run / non-run data is returned. | | mode | [sift.calculated\_channels.v1.ExpressionMode](#sift-calculated_channels-v1-expressionmode) | optional | Optional. If unset, will default to EXPRESSION\_MODE\_CALCULATED\_CHANNELS. | | combine\_run\_data | bool | optional | Optional. If unset, will default to false. If true, then requests that return data across multiple runs will be combined into a single result. This will apply to queries without a run, or when the requested run is an ad hoc run. This is useful when you prefer to see all the data as a single time series, instead of separated results by run. | ### ChannelQuery | Field | Type | Label | Description | | :---------- | :----- | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | channel\_id | string | | channel\_id is the uuid of the channel. | | run\_id | string | optional | Optional. If set, only data associated with the specified run is returned. If set to the empty string, only non-run data is returned. If unset, all run / non-run data is returned. | ### DimensionIndividualWrapper | Field | Type | Label | Description | | :-------------------------------------------------------- | :------------------------------------------------------------------ | :---- | :---------- | | label | string | | | | type | [DimensionIndividualWrapper.Type](#dimensionindividualwrapper-type) | | | | oneof value\_wrapper. dimension\_string\_values | [DimensionStringValues](#dimensionstringvalues) | | | | oneof value\_wrapper. dimension\_proto\_timestamp\_values | [DimensionProtoTimestampValues](#dimensionprototimestampvalues) | | | ### DimensionProtoTimestampValues | Field | Type | Label | Description | | :----- | :------------------------------------------------------------------------------------------------------------------------ | :------- | :---------- | | values | [DimensionProtoTimestampValues.DimensionProtoTimestampValue](#dimensionprototimestampvalues-dimensionprototimestampvalue) | repeated | | ### DimensionProtoTimestampValues.DimensionProtoTimestampValue | Field | Type | Label | Description | | :---- | :------------------------ | :------- | :---------- | | value | google.protobuf.Timestamp | optional | | ### DimensionStringValues | Field | Type | Label | Description | | :----- | :---------------------------------------------------------------------------------------- | :------- | :---------- | | values | [DimensionStringValues.DimensionStringValue](#dimensionstringvalues-dimensionstringvalue) | repeated | | ### DimensionStringValues.DimensionStringValue | Field | Type | Label | Description | | :---- | :----- | :------- | :---------- | | value | string | optional | | ### DoubleValue | Field | Type | Label | Description | | :-------- | :------------------------ | :---- | :---------- | | timestamp | google.protobuf.Timestamp | | | | value | double | | | ### DoubleValues | Field | Type | Label | Description | | :------- | :-------------------------------------------------------- | :------- | :---------- | | metadata | [Metadata](#metadata) | | | | values | [DoubleValue](#doublevalue) | repeated | | | extras | [DimensionIndividualWrapper](#dimensionindividualwrapper) | repeated | | ### EnumValue | Field | Type | Label | Description | | :-------- | :------------------------ | :---- | :---------- | | timestamp | google.protobuf.Timestamp | | | | value | uint32 | | | ### EnumValues | Field | Type | Label | Description | | :------- | :---------------------- | :------- | :---------- | | metadata | [Metadata](#metadata) | | | | values | [EnumValue](#enumvalue) | repeated | | ### FloatValue | Field | Type | Label | Description | | :-------- | :------------------------ | :---- | :---------- | | timestamp | google.protobuf.Timestamp | | | | value | float | | | ### FloatValues | Field | Type | Label | Description | | :------- | :-------------------------------------------------------- | :------- | :---------- | | metadata | [Metadata](#metadata) | | | | values | [FloatValue](#floatvalue) | repeated | | | extras | [DimensionIndividualWrapper](#dimensionindividualwrapper) | repeated | | ### GetDataRequest | Field | Type | Label | Description | | :-------------------- | :------------------------ | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | queries | [Query](#query) | repeated | | | start\_time | google.protobuf.Timestamp | | Required. The starting timestamp of the data to retrieve. This is an inclusive bound. | | end\_time | google.protobuf.Timestamp | | Required. The end timestamp of the data to retrieve. This is an exclusive bound. | | sample\_ms | uint32 | | The rate to sample the returned data at. The data is sampled using [LTTB](https://github.com/sveinn-steinarsson/flot-downsample) which will return one point approximately every sample\_ms milliseconds that retains the shape of the raw data. Sampling is only supported for numeric data types, if sample\_ms is provided for non-numeric data, it will be ignored and the full-fidelity data will be returned. A value of 0 disables sampling and returns the full unsampled dataset. This is recommended for external data analysis where full fidelity is required, as opposed to plotting where downsampling is typically sufficient. | | page\_size | uint32 | | The maximum number of channel values to return. The service may return fewer than this value. If unspecified, at most 10,000 values will be returned. The maximum value is 1,000,000; values above 1,000,000 will be coerced to 1,000,000. For variable data types (i.e. string channels), at most page\_size elements will be read, or 1MB, whichever occurs first. | | page\_token | string | | A page token, received from a previous `GetData` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `GetData` must match the call that provided the page token. | | include\_received\_at | bool | optional | Optional flag to enable inclusion of "sift\_received\_at" timestamps in GetDataResponse.data.extras field. | ### GetDataResponse | Field | Type | Label | Description | | :---------------- | :------------------ | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | next\_page\_token | string | | | | data | google.protobuf.Any | repeated | data contains the result of the supplied queries. Be aware that each query can generate multiple data responses. For example, if run\_id is omitted from a ChannelQuery, the query returns data for all runs containing that channel. Channel data for each run is returned in a separate data object. Possible message types: sift.data.v2.DoubleValues sift.data.v2.FloatValues sift.data.v2.StringValues sift.data.v2.EnumValues sift.data.v2.BitFieldValues sift.data.v2.BoolValues sift.data.v2.Int32Values sift.data.v2.Int64Values sift.data.v2.Uint32Values sift.data.v2.Uint64Values sift.data.v2.BytesValues | ### Int32Value | Field | Type | Label | Description | | :-------- | :------------------------ | :---- | :---------- | | timestamp | google.protobuf.Timestamp | | | | value | int32 | | | ### Int32Values | Field | Type | Label | Description | | :------- | :-------------------------------------------------------- | :------- | :---------- | | metadata | [Metadata](#metadata) | | | | values | [Int32Value](#int32value) | repeated | | | extras | [DimensionIndividualWrapper](#dimensionindividualwrapper) | repeated | | ### Int64Value | Field | Type | Label | Description | | :-------- | :------------------------ | :---- | :---------- | | timestamp | google.protobuf.Timestamp | | | | value | int64 | | | ### Int64Values | Field | Type | Label | Description | | :------- | :-------------------------------------------------------- | :------- | :---------- | | metadata | [Metadata](#metadata) | | | | values | [Int64Value](#int64value) | repeated | | | extras | [DimensionIndividualWrapper](#dimensionindividualwrapper) | repeated | | ### Metadata | Field | Type | Label | Description | | :---------- | :-------------------------------------------------------------------------- | :------- | :---------- | | data\_type | [sift.common.type.v1.ChannelDataType](#sift-common-type-v1-channeldatatype) | | | | sampled\_ms | uint32 | | | | asset | [Metadata.Asset](#metadata-asset) | | | | run | [Metadata.Run](#metadata-run) | optional | | | channel | [Metadata.Channel](#metadata-channel) | optional | | ### Metadata.Asset | Field | Type | Label | Description | | :-------- | :----- | :---- | :---------- | | asset\_id | string | | | | name | string | | | ### Metadata.Channel | Field | Type | Label | Description | | :------------------- | :---------------------------------------------------------------------------------------- | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------- | | channel\_id | string | | For channel queries, this will contain the requested backing channel id. For calculated channel queries, this will contain the requested channel key. | | name | string | | | | unit | [Metadata.Channel.Unit](#metadata-channel-unit) | | | | enum\_types | [sift.common.type.v1.ChannelEnumType](#sift-common-type-v1-channelenumtype) | repeated | | | bit\_field\_elements | [sift.common.type.v1.ChannelBitFieldElement](#sift-common-type-v1-channelbitfieldelement) | repeated | | ### Metadata.Channel.Unit | Field | Type | Label | Description | | :---------------- | :----- | :---- | :---------- | | name | string | | | | abbreviated\_name | string | | | ### Metadata.Run | Field | Type | Label | Description | | :------ | :----- | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------- | | run\_id | string | | The run\_id that was sent with the data during ingestion (if any). Note that this may be different from the run\_id that was requested in the query. | | name | string | | | ### Query | Field | Type | Label | Description | | :------------------------------- | :------------------------------------------------ | :---- | :---------- | | oneof query. channel | [ChannelQuery](#channelquery) | | | | oneof query. calculated\_channel | [CalculatedChannelQuery](#calculatedchannelquery) | | | ### StringValue | Field | Type | Label | Description | | :-------- | :------------------------ | :---- | :---------- | | timestamp | google.protobuf.Timestamp | | | | value | string | | | ### StringValues | Field | Type | Label | Description | | :------- | :-------------------------------------------------------- | :------- | :---------- | | metadata | [Metadata](#metadata) | | | | values | [StringValue](#stringvalue) | repeated | | | extras | [DimensionIndividualWrapper](#dimensionindividualwrapper) | repeated | | ### Uint32Value | Field | Type | Label | Description | | :-------- | :------------------------ | :---- | :---------- | | timestamp | google.protobuf.Timestamp | | | | value | uint32 | | | ### Uint32Values | Field | Type | Label | Description | | :------- | :-------------------------------------------------------- | :------- | :---------- | | metadata | [Metadata](#metadata) | | | | values | [Uint32Value](#uint32value) | repeated | | | extras | [DimensionIndividualWrapper](#dimensionindividualwrapper) | repeated | | ### Uint64Value | Field | Type | Label | Description | | :-------- | :------------------------ | :---- | :---------- | | timestamp | google.protobuf.Timestamp | | | | value | uint64 | | | ### Uint64Values | Field | Type | Label | Description | | :------- | :-------------------------------------------------------- | :------- | :---------- | | metadata | [Metadata](#metadata) | | | | values | [Uint64Value](#uint64value) | repeated | | | extras | [DimensionIndividualWrapper](#dimensionindividualwrapper) | repeated | | ## Enums *Allowed constant values used in message fields.* ### DimensionIndividualWrapper.Type | Name | Number | Description | | :--------------------------------- | :----- | :---------- | | TYPE\_UNSPECIFIED | 0 | | | TYPE\_IDENTIFIER | 1 | | | TYPE\_ADDITIONAL\_TIMESTAMP\_NANOS | 2 | | # data_imports Source: https://docs.siftstack.com/api/reference/protocol-buffers/data_imports sift/data_imports/v2/data_imports.proto ## Services *RPC methods exposed by this API.* ### DataImportService | Method | Request | Response | Description | | :------------------------- | :---------------------------------------------------------------------- | :------------------------------------------------------------------------ | :---------- | | CreateDataImportFromUrl | [CreateDataImportFromUrlRequest](#createdataimportfromurlrequest) | [CreateDataImportFromUrlResponse](#createdataimportfromurlresponse) | | | CreateDataImportFromUpload | [CreateDataImportFromUploadRequest](#createdataimportfromuploadrequest) | [CreateDataImportFromUploadResponse](#createdataimportfromuploadresponse) | | | DetectConfig | [DetectConfigRequest](#detectconfigrequest) | [DetectConfigResponse](#detectconfigresponse) | | | ListDataImports | [ListDataImportsRequest](#listdataimportsrequest) | [ListDataImportsResponse](#listdataimportsresponse) | | | RetryDataImport | [RetryDataImportRequest](#retrydataimportrequest) | [RetryDataImportResponse](#retrydataimportresponse) | | | GetDataImport | [GetDataImportRequest](#getdataimportrequest) | [GetDataImportResponse](#getdataimportresponse) | | ## Messages *Data models used across requests/responses.* ### BatchConfig | Field | Type | Label | Description | | :----------------------- | :------------------------------------------------------------ | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | run\_name | string | | Shared run for all files. Both are optional. If neither is set, data is ingested without a run. Run information must be set here instead of the per file configs if a Run is desired. | | run\_id | string | | | | asset\_name | string | | Default asset name for all files. The asset name must be set here instead of the per file configs. | | default\_csv\_config | [CsvConfig](#csvconfig) | | Per file type default configs. Multiple may be set for archives mixing file formats. A BatchFileConfig entry with no format config override inherits the default matching its type. | | default\_tdms\_config | [TDMSConfig](#tdmsconfig) | | | | default\_parquet\_config | [ParquetConfig](#parquetconfig) | | The default\_parquet\_config does not need to specify footer information. The importer will automatically extract footer information for the user. | | default\_hdf5\_config | [Hdf5Config](#hdf5config) | | | | default\_ulog\_config | [UlogConfig](#ulogconfig) | | | | default\_mcap\_config | [McapConfig](#mcapconfig) | | | | file\_configs | [BatchConfig.FileConfigsEntry](#batchconfig-fileconfigsentry) | repeated | Files to import. Key is the filepath as it appears within the archive. Only files listed here are imported; other archive files are ignored. | ### BatchConfig.FileConfigsEntry | Field | Type | Label | Description | | :---- | :---------------------------------- | :---- | :---------- | | key | string | | | | value | [BatchFileConfig](#batchfileconfig) | | | ### BatchFileConfig | Field | Type | Label | Description | | :---------------------------- | :------------------------------ | :---- | :---------------------------------------------------------------------------------------------------------------------------------------- | | type | [DataTypeKey](#datatypekey) | | Required. Specifies the format importer to use for this file. | | oneof config. csv\_config | [CsvConfig](#csvconfig) | | | | oneof config. tdms\_config | [TDMSConfig](#tdmsconfig) | | | | oneof config. parquet\_config | [ParquetConfig](#parquetconfig) | | The parquet\_config does not need to specify footer information. The importer will automatically extract footer information for the user. | | oneof config. hdf5\_config | [Hdf5Config](#hdf5config) | | | | oneof config. ulog\_config | [UlogConfig](#ulogconfig) | | | | oneof config. mcap\_config | [McapConfig](#mcapconfig) | | | ### Ch10Config | Field | Type | Label | Description | | :------------ | :----- | :---- | :---------- | | asset\_name | string | | | | run\_name | string | | | | scale\_values | bool | | | ### CreateDataImportFromUploadRequest | Field | Type | Label | Description | | :-------------- | :------------------------------ | :---- | :---------- | | csv\_config | [CsvConfig](#csvconfig) | | | | ch10\_config | [Ch10Config](#ch10config) | | | | tdms\_config | [TDMSConfig](#tdmsconfig) | | | | parquet\_config | [ParquetConfig](#parquetconfig) | | | | hdf5\_config | [Hdf5Config](#hdf5config) | | | | batch\_config | [BatchConfig](#batchconfig) | | | | ulog\_config | [UlogConfig](#ulogconfig) | | | | mcap\_config | [McapConfig](#mcapconfig) | | | ### CreateDataImportFromUploadResponse | Field | Type | Label | Description | | :--------------- | :----- | :---- | :---------- | | upload\_url | string | | | | data\_import\_id | string | | | ### CreateDataImportFromUrlRequest | Field | Type | Label | Description | | :-------------- | :------------------------------ | :---- | :---------------------------------------------------------------------------------------------------------------------------------- | | url | string | | The url to import. HTTP and S3 urls are supported. If you need to import non-public S3 objects, please contact Sift to set that up. | | csv\_config | [CsvConfig](#csvconfig) | | | | ch10\_config | [Ch10Config](#ch10config) | | | | tdms\_config | [TDMSConfig](#tdmsconfig) | | | | parquet\_config | [ParquetConfig](#parquetconfig) | | | | hdf5\_config | [Hdf5Config](#hdf5config) | | | | batch\_config | [BatchConfig](#batchconfig) | | | | ulog\_config | [UlogConfig](#ulogconfig) | | | | mcap\_config | [McapConfig](#mcapconfig) | | | ### CreateDataImportFromUrlResponse | Field | Type | Label | Description | | :--------------- | :----- | :---- | :---------- | | data\_import\_id | string | | | ### CsvConfig | Field | Type | Label | Description | | :-------------------- | :-------------------------------------------------------- | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | asset\_name | string | | | | run\_name | string | | | | run\_id | string | | The id of the run to add this data to. If set, `run_name` is ignored. | | first\_data\_row | uint32 | | The first row to start reading as data. Can be used to skip header rows. The first row in the file is 1. | | time\_column | [CsvTimeColumn](#csvtimecolumn) | optional | | | data\_columns | [CsvConfig.DataColumnsEntry](#csvconfig-datacolumnsentry) | repeated | A map from column number (1-indexed) to the channel configuration for that column. | | num\_rows | uint64 | optional | This will be read on upload from the file if not set. | | use\_embedded\_config | bool | | If true, the time and data column configuration is read from a config embedded in the file (written when the file was exported with embed\_channel\_configs). Any time\_column/data\_columns supplied here are ignored and replaced by the embedded config. | ### CsvConfig.DataColumnsEntry | Field | Type | Label | Description | | :---- | :---------------------------------------------------------------------- | :---- | :---------- | | key | uint32 | | | | value | [sift.common.type.v1.ChannelConfig](#sift-common-type-v1-channelconfig) | | | ### CsvTimeColumn | Field | Type | Label | Description | | :-------------------- | :------------------------ | :------- | :------------------------------------------------ | | column\_number | uint32 | | The column number (1-indexed) of the time column. | | format | [TimeFormat](#timeformat) | | | | relative\_start\_time | google.protobuf.Timestamp | optional | | ### DataImport | Field | Type | Label | Description | | :---------------- | :------------------------------------ | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | data\_import\_id | string | | | | source\_url | string | | | | status | [DataImportStatus](#dataimportstatus) | | | | error\_message | string | | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | csv\_config | [CsvConfig](#csvconfig) | | | | ch10\_config | [Ch10Config](#ch10config) | | | | tdms\_config | [TDMSConfig](#tdmsconfig) | | | | parquet\_config | [ParquetConfig](#parquetconfig) | | | | hdf5\_config | [Hdf5Config](#hdf5config) | | | | batch\_config | [BatchConfig](#batchconfig) | | | | ulog\_config | [UlogConfig](#ulogconfig) | | | | mcap\_config | [McapConfig](#mcapconfig) | | | | run\_id | string | optional | The run id will be set if the data import ingests to a run once the run is available. | | report\_id | string | optional | The report id will be set if the data import creates a report once the report is available. | | asset\_id | string | optional | | | data\_start\_time | google.protobuf.Timestamp | optional | | | data\_stop\_time | google.protobuf.Timestamp | optional | | | warning\_messages | string | repeated | What the import left out, such as records it could not read. A data import can succeed and still have warnings. The list may be trimmed; when it is, the last entry says how many were left off. | ### DetectConfigRequest | Field | Type | Label | Description | | :---- | :-------------------------- | :---- | :---------- | | data | bytes | | | | type | [DataTypeKey](#datatypekey) | | | ### DetectConfigResponse | Field | Type | Label | Description | | :-------------- | :------------------------------ | :---- | :---------- | | csv\_config | [CsvConfig](#csvconfig) | | | | parquet\_config | [ParquetConfig](#parquetconfig) | | | | hdf5\_config | [Hdf5Config](#hdf5config) | | | | tdms\_config | [TDMSConfig](#tdmsconfig) | | | ### GetDataImportRequest | Field | Type | Label | Description | | :--------------- | :----- | :---- | :---------- | | data\_import\_id | string | | | ### GetDataImportResponse | Field | Type | Label | Description | | :----------- | :------------------------ | :---- | :---------- | | data\_import | [DataImport](#dataimport) | | | ### Hdf5Config | Field | Type | Label | Description | | :-------------------- | :-------------------------------- | :------- | :-------------------------------------------------------------------- | | asset\_name | string | | | | run\_name | string | | | | run\_id | string | | The id of the run to add this data to. If set, `run_name` is ignored. | | data | [Hdf5DataConfig](#hdf5dataconfig) | repeated | | | time\_format | [TimeFormat](#timeformat) | | | | relative\_start\_time | google.protobuf.Timestamp | optional | | ### Hdf5DataConfig | Field | Type | Label | Description | | :-------------- | :---------------------------------------------------------------------- | :------- | :-------------------------------------------------------- | | time\_dataset | string | | | | time\_index | uint64 | | | | value\_dataset | string | | | | value\_index | uint64 | | | | channel\_config | [sift.common.type.v1.ChannelConfig](#sift-common-type-v1-channelconfig) | | | | time\_field | string | optional | For compound types, allow specifying which fields to use. | | value\_field | string | optional | | ### ListDataImportsRequest | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of data imports to return. The service may return fewer than this value. If unspecified, at most 50 data imports will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListDataImports` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListDataImports` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `data_import_id`, `source_url`, `status`, `run_id`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved data imports. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date` and `modified_date`. If left empty, items are ordered by `created_date` in ascending order (oldest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | ### ListDataImportsResponse | Field | Type | Label | Description | | :---------------- | :------------------------ | :------- | :---------- | | data\_imports | [DataImport](#dataimport) | repeated | | | next\_page\_token | string | | | ### McapConfig | Field | Type | Label | Description | | :--------------------------- | :-------------------------------------------------------- | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------- | | asset\_name | string | | | | run\_name | string | | | | run\_id | string | | The id of the run to add this data to. If set, `run_name` is ignored. | | data | [McapDataConfig](#mcapdataconfig) | repeated | Channels to import. Empty imports all detected channels with their defaults. If set, only the listed channels are imported, each with a required channel config. | | relative\_start\_time | google.protobuf.Timestamp | optional | Log-start UTC, only for logs on a non-Unix epoch. When set, `log_time` is reinterpreted as elapsed nanoseconds from this start. | | metadata\_records | string | repeated | Metadata records to import as run metadata. Every key of each named record is stored as `.`. Empty imports none. | | parse\_error\_policy | [McapParseErrorPolicy](#mcapparseerrorpolicy) | | Recoverable parse errors. Defaults to failing the import. | | complex\_types\_import\_mode | [McapComplexTypesImportMode](#mcapcomplextypesimportmode) | | Variable-cardinality fields. Defaults to importing them as both Arrow IPC bytes and JSON strings. | ### McapDataConfig | Field | Type | Label | Description | | :------------------- | :---------------------------------------------------------------------- | :---- | :---------------------------------------------------- | | topic | string | | The topic the channel comes from (e.g. "/imu/data"). | | oneof selector. ros2 | [McapRos2Selector](#mcapros2selector) | | | | channel\_config | [sift.common.type.v1.ChannelConfig](#sift-common-type-v1-channelconfig) | | The Sift channel config the channel is imported with. | ### McapRos2Selector | Field | Type | Label | Description | | :---------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------- | | field\_path | string | | The dot-delimited field path within the decoded message (e.g. "orientation.x", "orientation\_covariance\[0]"). | ### ParquetColumn | Field | Type | Label | Description | | :------------- | :---------------------------------------------------------------------- | :---- | :---------- | | path | string | | | | column\_config | [sift.common.type.v1.ChannelConfig](#sift-common-type-v1-channelconfig) | | | ### ParquetConfig | Field | Type | Label | Description | | :-------------------------------------- | :-------------------------------------------------------------------- | :---- | :-------------------------------------------------------------------- | | asset\_name | string | | | | run\_name | string | | | | run\_id | string | | The id of the run to add this data to. If set, `run_name` is ignored. | | oneof config. flat\_dataset | [ParquetFlatDatasetConfig](#parquetflatdatasetconfig) | | | | oneof config. single\_channel\_per\_row | [ParquetSingleChannelPerRowConfig](#parquetsinglechannelperrowconfig) | | | | footer\_offset | uint64 | | | | footer\_length | uint32 | | | | complex\_types\_import\_mode | [ParquetComplexTypesImportMode](#parquetcomplextypesimportmode) | | | ### ParquetDataColumn | Field | Type | Label | Description | | :-------------- | :---------------------------------------------------------------------- | :---- | :---------- | | path | string | | | | channel\_config | [sift.common.type.v1.ChannelConfig](#sift-common-type-v1-channelconfig) | | | ### ParquetFlatDatasetConfig | Field | Type | Label | Description | | :-------------------- | :-------------------------------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | time\_column | [ParquetTimeColumn](#parquettimecolumn) | | | | data\_columns | [ParquetDataColumn](#parquetdatacolumn) | repeated | | | use\_embedded\_config | bool | | If true, the time and data column configuration is read from the config embedded in the file's Arrow field metadata (written when the file was exported with embed\_channel\_configs). Any time\_column/data\_columns supplied here are ignored and replaced by the embedded config. | ### ParquetSingleChannelPerRowConfig | Field | Type | Label | Description | | :---------------------------- | :---------------------------------------------------------------------------------------------- | :------- | :------------------------------------- | | time\_column | [ParquetTimeColumn](#parquettimecolumn) | | Timestamp column configuration. | | columns | [ParquetColumn](#parquetcolumn) | repeated | Detected columns. | | oneof config. single\_channel | [ParquetSingleChannelPerRowSingleChannelConfig](#parquetsinglechannelperrowsinglechannelconfig) | | Single channel per file configuration. | | oneof config. multi\_channel | [ParquetSingleChannelPerRowMultiChannelConfig](#parquetsinglechannelperrowmultichannelconfig) | | Multi-channel per file configuration. | ### ParquetSingleChannelPerRowMultiChannelConfig | Field | Type | Label | Description | | :--------- | :------------------------------------------------------------------------------------------------------------------------ | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | name\_path | string | | | | data\_path | string | | | | channels | [ParquetSingleChannelPerRowMultiChannelConfig.ChannelsEntry](#parquetsinglechannelperrowmultichannelconfig-channelsentry) | repeated | A map from names (from `name_path`) to the channel configuration for that name. Names without an entry are imported with the data column's data type and no other configuration. | ### ParquetSingleChannelPerRowMultiChannelConfig.ChannelsEntry | Field | Type | Label | Description | | :---- | :---------------------------------------------------------------------- | :---- | :---------- | | key | string | | | | value | [sift.common.type.v1.ChannelConfig](#sift-common-type-v1-channelconfig) | | | ### ParquetSingleChannelPerRowSingleChannelConfig | Field | Type | Label | Description | | :--------- | :---------------------------------------------------------------------- | :---- | :---------- | | data\_path | string | | | | channel | [sift.common.type.v1.ChannelConfig](#sift-common-type-v1-channelconfig) | | | ### ParquetTimeColumn | Field | Type | Label | Description | | :-------------------- | :------------------------ | :------- | :---------- | | path | string | | | | format | [TimeFormat](#timeformat) | | | | relative\_start\_time | google.protobuf.Timestamp | optional | | ### RetryDataImportRequest | Field | Type | Label | Description | | :--------------- | :----- | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | data\_import\_id | string | | data\_import\_id is the id of the data import to retry. You can only retry an import that is a "url" based import (created with CreateDataImportFromUrl) and is in a failed state. | ### RetryDataImportResponse *This message has no fields.* ### TDMSConfig | Field | Type | Label | Description | | :----------------------- | :---------------------------------------- | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | asset\_name | string | | | | run\_name | string | | | | start\_time\_override | google.protobuf.Timestamp | | Override the wf\_start\_time metadata field for all channels. Useful if your waveform channels have wf\_increment but no wf\_start\_time (Veristand is guilty of this). | | file\_size | uint64 | optional | **Deprecated.** The file size in bytes. If the file has truncated chunks, this will be required to pass validation. | | run\_id | string | | The id of the run to add this data to. If set, `run_name` is ignored. | | data | [TdmsDataConfig](#tdmsdataconfig) | repeated | If no data entries are present attempt to ingest everything relying on the fallback method for any ambiguous channels. | | fallback\_method | [TdmsFallbackMethod](#tdmsfallbackmethod) | | The fallback method for channels with missing timing information. | | time\_format | [TimeFormat](#timeformat) | optional | Time format for time channels not using the TDMS timestamp type. | | relative\_start\_time | google.protobuf.Timestamp | optional | Relative start time for channels using a non standard time channel. | | import\_file\_properties | bool | | If true, will import TDMS file properties to the run as metadata. Only valid if a run\_name or run\_id is set. | ### TdmsDataConfig | Field | Type | Label | Description | | :------------------ | :---------------------------------------------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------- | | group\_name | string | | The TDMS group name associated with this channel. | | channel\_name | string | | The TDMS channel name associated with this channel. | | channel\_config | [sift.common.type.v1.ChannelConfig](#sift-common-type-v1-channelconfig) | | The Sift channel config. | | time\_channel\_name | string | optional | The time channel associated with this channel. If this is empty then we assume it's a waveform channel with waveform properties. | | scaled | bool | optional | Whether to import scaled or raw values. Defaults to True to import scaled values. | | complex\_component | [TdmsComplexComponent](#tdmscomplexcomponent) | optional | Whether to import the real or imaginary component. Only applies to complex data types. Defaults to real. | ### UlogConfig | Field | Type | Label | Description | | :-------------------- | :-------------------------------------------- | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | asset\_name | string | | | | run\_name | string | | | | run\_id | string | | The id of the run to add this data to. If set, `run_name` is ignored. | | data | [UlogDataConfig](#ulogdataconfig) | repeated | Channels to import. Empty imports all detected channels with their defaults; if set, only the listed channels are imported, each with a required channel config. | | relative\_start\_time | google.protobuf.Timestamp | optional | Log-start UTC. When set, it anchors the timeline and takes precedence over the log's GPS fix; otherwise the GPS fix anchors the timeline. The import fails if neither is available. | | info\_keys | string | repeated | I/M message info keys to import as run metadata (stored as info.). Empty: none. | | param\_keys | string | repeated | P parameter names to import as run metadata (stored as param.). Empty: none. | | parse\_error\_policy | [UlogParseErrorPolicy](#ulogparseerrorpolicy) | | Recoverable parse errors; defaults to failing the import. | ### UlogDataConfig | Field | Type | Label | Description | | :-------------- | :---------------------------------------------------------------------- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | message\_name | string | | The ULog message name (e.g. "sensor\_accel"). | | instance | int64 | | The message instance (e.g. 0). | | field\_name | string | | The full ULog field name (e.g. "x", "esc\[0].v"). Empty for log-message channels ("log\_messages", "log\_messages\_"), which set message\_name to the channel name and instance to 0. | | channel\_config | [sift.common.type.v1.ChannelConfig](#sift-common-type-v1-channelconfig) | | The Sift channel config the channel is imported with. | ## Enums *Allowed constant values used in message fields.* ### DataImportStatus | Name | Number | Description | | :--------------------------------- | :----- | :-------------- | | DATA\_IMPORT\_STATUS\_UNSPECIFIED | 0 | **Deprecated.** | | DATA\_IMPORT\_STATUS\_PENDING | 1 | | | DATA\_IMPORT\_STATUS\_IN\_PROGRESS | 2 | | | DATA\_IMPORT\_STATUS\_SUCCEEDED | 3 | | | DATA\_IMPORT\_STATUS\_FAILED | 4 | | ### DataTypeKey | Name | Number | Description | | :-------------------------------------------------- | :----- | :-------------- | | DATA\_TYPE\_KEY\_UNSPECIFIED | 0 | **Deprecated.** | | DATA\_TYPE\_KEY\_CSV | 1 | | | DATA\_TYPE\_KEY\_TDMS | 2 | | | DATA\_TYPE\_KEY\_CH10 | 3 | | | DATA\_TYPE\_KEY\_PARQUET\_FLATDATASET | 4 | | | DATA\_TYPE\_KEY\_PARQUET\_SINGLE\_CHANNEL\_PER\_ROW | 5 | | | DATA\_TYPE\_KEY\_HDF5 | 6 | | | DATA\_TYPE\_KEY\_ULOG | 7 | | | DATA\_TYPE\_KEY\_MCAP | 8 | | ### McapComplexTypesImportMode | Name | Number | Description | | :---------------------------------------------- | :----- | :--------------------------------------------------------------------------- | | MCAP\_COMPLEX\_TYPES\_IMPORT\_MODE\_UNSPECIFIED | 0 | Treated as MCAP\_COMPLEX\_TYPES\_IMPORT\_MODE\_BOTH. | | MCAP\_COMPLEX\_TYPES\_IMPORT\_MODE\_IGNORE | 1 | Ignore variable-cardinality fields and do not ingest them. | | MCAP\_COMPLEX\_TYPES\_IMPORT\_MODE\_BOTH | 2 | Import variable-cardinality fields as both Arrow IPC bytes and JSON strings. | | MCAP\_COMPLEX\_TYPES\_IMPORT\_MODE\_STRING | 3 | Import variable-cardinality fields as only JSON strings. | | MCAP\_COMPLEX\_TYPES\_IMPORT\_MODE\_BYTES | 4 | Import variable-cardinality fields as only Arrow IPC bytes. | ### McapParseErrorPolicy | Name | Number | Description | | :------------------------------------------ | :----- | :------------------------------------------------------------------- | | MCAP\_PARSE\_ERROR\_POLICY\_UNSPECIFIED | 0 | Treated as MCAP\_PARSE\_ERROR\_POLICY\_FAIL\_ON\_ERROR. | | MCAP\_PARSE\_ERROR\_POLICY\_FAIL\_ON\_ERROR | 1 | Fail the import on any recoverable parse error. | | MCAP\_PARSE\_ERROR\_POLICY\_IGNORE\_ERROR | 2 | Import what decoded. Skipped topics and records surface as warnings. | ### ParquetComplexTypesImportMode | Name | Number | Description | | :------------------------------------------------- | :----- | :--------------------------------------------------------- | | PARQUET\_COMPLEX\_TYPES\_IMPORT\_MODE\_UNSPECIFIED | 0 | **Deprecated.** | | PARQUET\_COMPLEX\_TYPES\_IMPORT\_MODE\_IGNORE | 1 | Ignore complex types and do not ingest them. | | PARQUET\_COMPLEX\_TYPES\_IMPORT\_MODE\_BOTH | 2 | Import complex types as both Arrow bytes and JSON strings. | | PARQUET\_COMPLEX\_TYPES\_IMPORT\_MODE\_STRING | 3 | Import complex types as only JSON strings. | | PARQUET\_COMPLEX\_TYPES\_IMPORT\_MODE\_BYTES | 4 | Import complex types as only Arrow bytes. | ### TdmsComplexComponent | Name | Number | Description | | :------------------------------------ | :----- | :--------------------------------------- | | TDMS\_COMPLEX\_COMPONENT\_UNSPECIFIED | 0 | Default is to select the real component. | | TDMS\_COMPLEX\_COMPONENT\_REAL | 1 | | | TDMS\_COMPLEX\_COMPONENT\_IMAGINARY | 2 | | ### TdmsFallbackMethod The fallback method tells the importer how to treat channels without any timing information (i.e, waveform properties or time channels). | Name | Number | Description | | :-------------------------------------- | :----- | :-------------------------------------------------------------------------- | | TDMS\_FALLBACK\_METHOD\_UNSPECIFIED | 0 | **Deprecated.** | | TDMS\_FALLBACK\_METHOD\_FAIL\_ON\_ERROR | 1 | Fails the import if any specified channels have missing timing information. | | TDMS\_FALLBACK\_METHOD\_IGNORE\_ERROR | 2 | Ignores channels without any timing information. | ### TimeFormat | Name | Number | Description | | :----------------------------------------- | :----- | :---------- | | TIME\_FORMAT\_UNSPECIFIED | 0 | | | TIME\_FORMAT\_RELATIVE\_NANOSECONDS | 1 | | | TIME\_FORMAT\_RELATIVE\_MICROSECONDS | 2 | | | TIME\_FORMAT\_RELATIVE\_MILLISECONDS | 3 | | | TIME\_FORMAT\_RELATIVE\_SECONDS | 4 | | | TIME\_FORMAT\_RELATIVE\_MINUTES | 5 | | | TIME\_FORMAT\_RELATIVE\_HOURS | 6 | | | TIME\_FORMAT\_ABSOLUTE\_RFC3339 | 10 | | | TIME\_FORMAT\_ABSOLUTE\_DATETIME | 11 | | | TIME\_FORMAT\_ABSOLUTE\_UNIX\_SECONDS | 12 | | | TIME\_FORMAT\_ABSOLUTE\_UNIX\_MILLISECONDS | 13 | | | TIME\_FORMAT\_ABSOLUTE\_UNIX\_MICROSECONDS | 14 | | | TIME\_FORMAT\_ABSOLUTE\_UNIX\_NANOSECONDS | 15 | | ### UlogParseErrorPolicy | Name | Number | Description | | :------------------------------------------ | :----- | :------------------------------------------------------ | | ULOG\_PARSE\_ERROR\_POLICY\_UNSPECIFIED | 0 | Treated as ULOG\_PARSE\_ERROR\_POLICY\_FAIL\_ON\_ERROR. | | ULOG\_PARSE\_ERROR\_POLICY\_FAIL\_ON\_ERROR | 1 | Fail the import on any recoverable parse error. | | ULOG\_PARSE\_ERROR\_POLICY\_IGNORE\_ERROR | 2 | Import what parsed; skipped records are logged. | # dlq_errors Source: https://docs.siftstack.com/api/reference/protocol-buffers/dlq_errors sift/dlq_errors/v2/dlq_errors.proto ## Services *RPC methods exposed by this API.* ### DlqErrorsService | Method | Request | Response | Description | | :------------ | :-------------------------------------------- | :---------------------------------------------- | :---------- | | ListDlqErrors | [ListDlqErrorsRequest](#listdlqerrorsrequest) | [ListDlqErrorsResponse](#listdlqerrorsresponse) | | ## Messages *Data models used across requests/responses.* ### ErrorSummary | Field | Type | Label | Description | | :--------------------- | :------------------------ | :------- | :---------- | | count | uint64 | | | | asset\_name | string | optional | | | min\_timestamp | google.protobuf.Timestamp | | | | max\_timestamp | google.protobuf.Timestamp | | | | dlq\_parquet\_file\_id | string | | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | ### ListDlqErrorsRequest | Field | Type | Label | Description | | :---------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | page\_size | uint32 | | The maximum number of errors values to return. The service may return fewer than this value. If unspecified, at most 50 values will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. | | page\_token | string | | A page token, received from a previous `ListDlqErrors` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListDlqErrors` must match the call that provided the page token. | | filter | string | | A Common Expression Language (CEL, [https://github.com/google/cel-spec](https://github.com/google/cel-spec)) filter string. Available tag variables are: - min\_timestamp - max\_timestamp - asset\_id | | order\_by | string | | How to order the retrieved campaigns. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `min_timestamp`, `max_timestamp`, and `asset_id`. If left empty, items are ordered by `min_timestamp` in ascending order (oldest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "asset\_id desc,min\_timestamp" | ### ListDlqErrorsResponse | Field | Type | Label | Description | | :---------------- | :---------------------------- | :------- | :---------- | | error\_summaries | [ErrorSummary](#errorsummary) | repeated | | | next\_page\_token | string | | | ## Enums *Allowed constant values used in message fields.* # docs Source: https://docs.siftstack.com/api/reference/protocol-buffers/docs sift/docs/v1/docs.proto ## Services *RPC methods exposed by this API.* ### DocsService DocsService exposes read-only access to Sift's bundled product documentation (docs.siftstack.com). Tools such as the Sift MCP server can search and read the docs over HTTP with the same bearer token / API key used for the rest of the Sift API. | Method | Request | Response | Description | | :--------- | :-------------------------------------- | :---------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | SearchDocs | [SearchDocsRequest](#searchdocsrequest) | [SearchDocsResponse](#searchdocsresponse) | SearchDocs runs a keyword search across the bundled docs and returns ranked pages, each with the best-matching line and a line-numbered window of surrounding context. Follow up with ReadDoc on a promising hit. | | ReadDoc | [ReadDocRequest](#readdocrequest) | [ReadDocResponse](#readdocresponse) | ReadDoc returns the markdown for a single doc page by path, optionally sliced by 1-indexed offset/limit for long reference pages. | ## Messages *Data models used across requests/responses.* ### DocHit | Field | Type | Label | Description | | :----------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------ | | path | string | | Doc path, e.g. "documentation/ingest/asset-channels.mdx". Pass to ReadDoc. | | title | string | | | | score | int32 | | Relevance score; higher is more relevant. Title matches weigh most, then headings, then body. | | match\_line | int32 | | 1-indexed line number of the best match, in the same coordinates as ReadDoc; pass to ReadDoc as offset to see more. | | total\_lines | int32 | | Total line count of the page. | | content | string | | Window of the 10 lines above and below match\_line, clamped to the page. Each line is prefixed with "\t", aligned with ReadDoc. | ### ReadDocRequest | Field | Type | Label | Description | | :----- | :----- | :---- | :----------------------------------------------------------------------------------------- | | path | string | | Doc path returned by SearchDocs, e.g. "documentation/ingest/asset-channels.mdx". Required. | | offset | int32 | | 1-indexed start line. Defaults to 1. Optional. | | limit | int32 | | Number of lines to return. Defaults to all remaining lines. Optional. | ### ReadDocResponse | Field | Type | Label | Description | | :----------- | :----- | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------------- | | path | string | | | | title | string | | | | total\_lines | int32 | | Total line count of the page (independent of offset/limit). | | start\_line | int32 | | 1-indexed line number of the first returned line. | | content | string | | Page markdown. Each line is prefixed with "\t" so follow-up reads can target specific ranges. MDX/JSX tags are stripped; fenced code blocks are preserved. | ### SearchDocsRequest | Field | Type | Label | Description | | :----------- | :----- | :---- | :--------------------------------------------------------------------------------------------------- | | query | string | | Keyword query, e.g. "asset channels CEL". Required. | | max\_results | int32 | | Maximum hits to return. Defaults to 10; values above the hard cap of 25 are coerced to 25. Optional. | ### SearchDocsResponse | Field | Type | Label | Description | | :------------- | :---------------- | :------- | :------------------------------------------------------- | | hits | [DocHit](#dochit) | repeated | | | total\_scanned | int32 | | Total number of doc pages scanned to produce these hits. | ## Enums *Allowed constant values used in message fields.* # exports Source: https://docs.siftstack.com/api/reference/protocol-buffers/exports sift/exports/v1/exports.proto ## Services *RPC methods exposed by this API.* ### ExportService | Method | Request | Response | Description | | :------------- | :---------------------------------------------- | :------------------------------------------------ | :---------- | | ExportData | [ExportDataRequest](#exportdatarequest) | [ExportDataResponse](#exportdataresponse) | | | GetDownloadUrl | [GetDownloadUrlRequest](#getdownloadurlrequest) | [GetDownloadUrlResponse](#getdownloadurlresponse) | | ## Messages *Data models used across requests/responses.* ### AssetsAndTimeRange | Field | Type | Label | Description | | :---------- | :------------------------ | :------- | :---------- | | asset\_ids | string | repeated | | | start\_time | google.protobuf.Timestamp | | | | stop\_time | google.protobuf.Timestamp | | | ### CalculatedChannelConfig | Field | Type | Label | Description | | :------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------- | :------- | :---------- | | name | string | | | | expression | string | | | | channel\_references | [sift.calculated\_channels.v2.CalculatedChannelAbstractChannelReference](#sift-calculated_channels-v2-calculatedchannelabstractchannelreference) | repeated | | | units | string | optional | | ### ExportDataRequest | Field | Type | Label | Description | | :---------------------------------------------- | :-------------------------------------------------- | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | oneof time\_selection. time\_range | [TimeRange](#timerange) | | If time\_range used, channel\_ids or calculated\_chanel\_configs must be provided to scope data. | | oneof time\_selection. runs\_and\_time\_range | [RunsAndTimeRange](#runsandtimerange) | | Runs used to perform time selection and scope data. Times can optionally be provided to further scope within runs. If channel\_ids or calculated\_channel\_configs not provided, all channels from Run Assets are added to scope. | | oneof time\_selection. assets\_and\_time\_range | [AssetsAndTimeRange](#assetsandtimerange) | | Assets and times provided to scope data. If channel\_ids or calculated\_channel\_configs not provided, all channels from Assets are added to scope. | | channel\_ids | string | repeated | | | calculated\_channel\_configs | [CalculatedChannelConfig](#calculatedchannelconfig) | repeated | | | output\_format | [ExportOutputFormat](#exportoutputformat) | | | | export\_options | [ExportOptions](#exportoptions) | | | ### ExportDataResponse | Field | Type | Label | Description | | :--------------- | :----- | :---- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | presigned\_url | string | | Pre-signed URL of exported zip containing export files. This will be blank if the job is processed as a background job, in which case `job_id` will be non-empty. | | job\_id | string | | This will be non-empty if the export is being processed asynchronously in a background job. | | service\_message | string | | Optional message for the client to display in success or error notification (e.g. exclusions or 403 reason). | ### ExportOptions | Field | Type | Label | Description | | :----------------------- | :--- | :---- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | use\_legacy\_format | bool | | Whether to use legacy format string for channel headers which contains key-value metadata. | | simplify\_channel\_names | bool | | Whether to simplify channel names by removing the component part of the name if name is unique in export file | | combine\_runs | bool | | Whether to combine runs. e.g. channels from the same asset in different runs will be combined into a single column of data. | | split\_export\_by\_asset | bool | | Split each asset into their own export file | | split\_export\_by\_run | bool | | Split each run into their own export file | | embed\_channel\_configs | bool | | Embeds a re-importable channel configuration into the export: for CSV, as a config row inserted immediately after the header row; for Parquet, as per-column field metadata under the "sift\_channel\_config" key. Ignored for the SUN output format. | ### GetDownloadUrlRequest | Field | Type | Label | Description | | :------ | :----- | :---- | :---------- | | job\_id | string | | | ### GetDownloadUrlResponse | Field | Type | Label | Description | | :--------------- | :----- | :---- | :--------------------------------------------------------------------------- | | presigned\_url | string | | | | service\_message | string | | Optional message for the client to display in success or error notification. | ### RunsAndTimeRange | Field | Type | Label | Description | | :---------- | :------------------------ | :------- | :---------- | | run\_ids | string | repeated | | | start\_time | google.protobuf.Timestamp | | | | stop\_time | google.protobuf.Timestamp | | | ### TimeRange | Field | Type | Label | Description | | :---------- | :------------------------ | :---- | :---------- | | start\_time | google.protobuf.Timestamp | | | | stop\_time | google.protobuf.Timestamp | | | ## Enums *Allowed constant values used in message fields.* ### ExportOutputFormat | Name | Number | Description | | :---------------------------------- | :----- | :---------- | | EXPORT\_OUTPUT\_FORMAT\_UNSPECIFIED | 0 | | | EXPORT\_OUTPUT\_FORMAT\_CSV | 1 | | | EXPORT\_OUTPUT\_FORMAT\_SUN | 2 | | | EXPORT\_OUTPUT\_FORMAT\_PARQUET | 3 | | # external_sync Source: https://docs.siftstack.com/api/reference/protocol-buffers/external_sync sift/external_sync/v1/external_sync.proto ## Services *RPC methods exposed by this API.* ### ExternalSyncService | Method | Request | Response | Description | | :---------------------------- | :---------------------------------------------------------------------------- | :------------------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | SyncOrganization | [SyncOrganizationRequest](#syncorganizationrequest) | [SyncOrganizationResponse](#syncorganizationresponse) | | | GenerateToken | [GenerateTokenRequest](#generatetokenrequest) | [GenerateTokenResponse](#generatetokenresponse) | | | GetExternalSync | [GetExternalSyncRequest](#getexternalsyncrequest) | [GetExternalSyncResponse](#getexternalsyncresponse) | | | ListExternalSyncTokens | [ListExternalSyncTokensRequest](#listexternalsynctokensrequest) | [ListExternalSyncTokensResponse](#listexternalsynctokensresponse) | | | ListExternalSyncRuns | [ListExternalSyncRunsRequest](#listexternalsyncrunsrequest) | [ListExternalSyncRunsResponse](#listexternalsyncrunsresponse) | | | GetExternalSyncRun | [GetExternalSyncRunRequest](#getexternalsyncrunrequest) | [GetExternalSyncRunResponse](#getexternalsyncrunresponse) | | | GetIsOrgExternallyProvisioned | [GetIsOrgExternallyProvisionedRequest](#getisorgexternallyprovisionedrequest) | [GetIsOrgExternallyProvisionedResponse](#getisorgexternallyprovisionedresponse) | Organization admins (Admin role in the org) and platform admins may call. Returns whether the org has IdP/SCIM external sync configured (users should be provisioned via the identity provider). Organization is taken from request context. | ## Messages *Data models used across requests/responses.* ### ExternalSync | Field | Type | Label | Description | | :-------------------------------- | :------------------------ | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | organization\_id | string | | | | most\_recent\_sync\_date | google.protobuf.Timestamp | optional | | | most\_recent\_sync\_by\_user\_id | string | optional | | | scim\_server\_url | string | | | | token\_created\_date | google.protobuf.Timestamp | optional | | | token\_lifetime\_seconds | uint32 | | | | most\_recent\_token\_by\_user\_id | string | optional | | | realm | string | | The Keycloak realm the sync reads from. Already stored alongside the sync; returned here so customer admins can reference it. | | client | string | | The Keycloak client id the sync authenticates as. Already stored alongside the sync; returned here so customer admins can reference it. The corresponding client secret stays write-only and is never returned. | ### ExternalSyncGroupRef Sift user group identity for display (group\_name) and stable API use (user\_group\_id). | Field | Type | Label | Description | | :-------------- | :----- | :---- | :---------- | | user\_group\_id | string | | | | group\_name | string | | | ### ExternalSyncMembershipChange One membership edge that changed during the sync. | Field | Type | Label | Description | | :-------------- | :----- | :---- | :---------- | | user\_id | string | | | | user\_name | string | | | | user\_group\_id | string | | | | group\_name | string | | | ### ExternalSyncRun | Field | Type | Label | Description | | :---------------------- | :-------------------------------------------------------- | :------- | :---------- | | external\_sync\_run\_id | string | | | | synced\_at | google.protobuf.Timestamp | | | | trigger\_type | [ExternalSyncRunTriggerType](#externalsyncruntriggertype) | | | | triggered\_by\_user\_id | string | optional | | | diff | [ExternalSyncRunDiff](#externalsyncrundiff) | | | ### ExternalSyncRunDiff Snapshot of membership and lifecycle changes from one external sync run. Identifiers are Sift `user_id` / `user_group_id` UUIDs and human-readable names as stored in Sift (not Keycloak SCIM ids). Older stored runs may have empty ids with names only. | Field | Type | Label | Description | | :--------------------------- | :------------------------------------------------------------ | :------- | :---------- | | users\_activated | [ExternalSyncUserRef](#externalsyncuserref) | repeated | | | users\_deactivated | [ExternalSyncUserRef](#externalsyncuserref) | repeated | | | groups\_created | [ExternalSyncGroupRef](#externalsyncgroupref) | repeated | | | groups\_deleted | [ExternalSyncGroupRef](#externalsyncgroupref) | repeated | | | users\_added\_to\_groups | [ExternalSyncMembershipChange](#externalsyncmembershipchange) | repeated | | | users\_removed\_from\_groups | [ExternalSyncMembershipChange](#externalsyncmembershipchange) | repeated | | ### ExternalSyncRunSummary | Field | Type | Label | Description | | :---------------------------------- | :-------------------------------------------------------- | :------- | :---------- | | external\_sync\_run\_id | string | | | | synced\_at | google.protobuf.Timestamp | | | | trigger\_type | [ExternalSyncRunTriggerType](#externalsyncruntriggertype) | | | | triggered\_by\_user\_id | string | optional | | | users\_activated\_count | uint32 | | | | users\_deactivated\_count | uint32 | | | | groups\_created\_count | uint32 | | | | groups\_deleted\_count | uint32 | | | | users\_added\_to\_groups\_count | uint32 | | | | users\_removed\_from\_groups\_count | uint32 | | | ### ExternalSyncToken The actual token value is not returned after it is first generated. | Field | Type | Label | Description | | :-------------------- | :------------------------ | :---- | :---------- | | token\_id | string | | | | lifetime\_seconds | uint32 | | | | created\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | ### ExternalSyncUserRef Sift user identity for display (user\_name) and stable API use (user\_id). | Field | Type | Label | Description | | :--------- | :----- | :---- | :---------- | | user\_id | string | | | | user\_name | string | | | ### GenerateTokenRequest *This message has no fields.* ### GenerateTokenResponse | Field | Type | Label | Description | | :------------- | :---------------------------- | :---- | :---------- | | external\_sync | [ExternalSync](#externalsync) | | | | token | string | | | ### GetExternalSyncRequest *This message has no fields.* ### GetExternalSyncResponse | Field | Type | Label | Description | | :------------- | :---------------------------- | :---- | :---------- | | success | bool | | | | external\_sync | [ExternalSync](#externalsync) | | | ### GetExternalSyncRunRequest | Field | Type | Label | Description | | :---------------------- | :----- | :---- | :---------- | | external\_sync\_run\_id | string | | | ### GetExternalSyncRunResponse | Field | Type | Label | Description | | :------------------ | :---------------------------------- | :---- | :---------- | | external\_sync\_run | [ExternalSyncRun](#externalsyncrun) | | | ### GetIsOrgExternallyProvisionedRequest *This message has no fields.* ### GetIsOrgExternallyProvisionedResponse | Field | Type | Label | Description | | :-------------------------- | :--- | :---- | :---------- | | is\_externally\_provisioned | bool | | | ### ListExternalSyncRunsRequest | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------- | | page\_size | uint32 | | | | page\_token | string | | | | filter | string | | | | order\_by | string | | | ### ListExternalSyncRunsResponse | Field | Type | Label | Description | | :----------------------------- | :------------------------------------------------ | :------- | :---------- | | external\_sync\_run\_summaries | [ExternalSyncRunSummary](#externalsyncrunsummary) | repeated | | | next\_page\_token | string | | | ### ListExternalSyncTokensRequest | Field | Type | Label | Description | | :---------- | :----- | :---- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of tokens to return. The service may return fewer than this value. If unspecified, at most 50 tokens will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListExternalSyncTokens` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListExternalSyncTokens` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. There are currently no available fields. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved user defined functions. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available field to order\_by is `created_date`. If left empty, items are ordered by `created_date` in descending order (newest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date asc". | ### ListExternalSyncTokensResponse | Field | Type | Label | Description | | :--------------------- | :-------------------------------------- | :------- | :---------- | | external\_sync\_tokens | [ExternalSyncToken](#externalsynctoken) | repeated | | | next\_page\_token | string | | | ### SyncOrganizationRequest *This message has no fields.* ### SyncOrganizationResponse | Field | Type | Label | Description | | :--------------------------------- | :--------------------------------------------------------------- | :------- | :---------- | | external\_sync | [ExternalSync](#externalsync) | | | | existing\_user\_count | uint32 | | | | added\_to\_organization\_user\_ids | string | repeated | | | created\_users | [sift.common.type.v1.User](#sift-common-type-v1-user) | repeated | | | deactivated\_user\_ids | string | repeated | | | existing\_group\_count | uint32 | | | | created\_user\_groups | [sift.user\_groups.v2.UserGroup](#sift-user_groups-v2-usergroup) | repeated | | | deleted\_user\_group\_names | string | repeated | | ## Enums *Allowed constant values used in message fields.* ### ExternalSyncRunTriggerType | Name | Number | Description | | :----------------------------------------------- | :----- | :------------------------------------------ | | EXTERNAL\_SYNC\_RUN\_TRIGGER\_TYPE\_UNSPECIFIED | 0 | | | EXTERNAL\_SYNC\_RUN\_TRIGGER\_TYPE\_MANUAL\_USER | 1 | User triggered sync via the Sift UI or API. | | EXTERNAL\_SYNC\_RUN\_TRIGGER\_TYPE\_SCHEDULED | 2 | | # families Source: https://docs.siftstack.com/api/reference/protocol-buffers/families sift/families/v1/families.proto ## Services *RPC methods exposed by this API.* ### FamilyService | Method | Request | Response | Description | | :-------------------------- | :------------------------------------------------------------------------ | :-------------------------------------------------------------------------- | :---------- | | GetFamily | [GetFamilyRequest](#getfamilyrequest) | [GetFamilyResponse](#getfamilyresponse) | | | GetFamilies | [GetFamiliesRequest](#getfamiliesrequest) | [GetFamiliesResponse](#getfamiliesresponse) | | | GetFamilyVersion | [GetFamilyVersionRequest](#getfamilyversionrequest) | [GetFamilyVersionResponse](#getfamilyversionresponse) | | | CreateFamily | [CreateFamilyRequest](#createfamilyrequest) | [CreateFamilyResponse](#createfamilyresponse) | | | UpdateFamily | [UpdateFamilyRequest](#updatefamilyrequest) | [UpdateFamilyResponse](#updatefamilyresponse) | | | GetFamilyCandidateRuns | [GetFamilyCandidateRunsRequest](#getfamilycandidaterunsrequest) | [GetFamilyCandidateRunsResponse](#getfamilycandidaterunsresponse) | | | GetFamilyCandidateRunCount | [GetFamilyCandidateRunCountRequest](#getfamilycandidateruncountrequest) | [GetFamilyCandidateRunCountResponse](#getfamilycandidateruncountresponse) | | | ListFamilyCandidateRuns | [ListFamilyCandidateRunsRequest](#listfamilycandidaterunsrequest) | [ListFamilyCandidateRunsResponse](#listfamilycandidaterunsresponse) | | | ListFamilies | [ListFamiliesRequest](#listfamiliesrequest) | [ListFamiliesResponse](#listfamiliesresponse) | | | ListFamilyVersions | [ListFamilyVersionsRequest](#listfamilyversionsrequest) | [ListFamilyVersionsResponse](#listfamilyversionsresponse) | | | ListFamilyMembers | [ListFamilyMembersRequest](#listfamilymembersrequest) | [ListFamilyMembersResponse](#listfamilymembersresponse) | | | ListFamilyAlignments | [ListFamilyAlignmentsRequest](#listfamilyalignmentsrequest) | [ListFamilyAlignmentsResponse](#listfamilyalignmentsresponse) | | | ListFamilyAlignmentPoints | [ListFamilyAlignmentPointsRequest](#listfamilyalignmentpointsrequest) | [ListFamilyAlignmentPointsResponse](#listfamilyalignmentpointsresponse) | | | ImportFamily | [ImportFamilyRequest](#importfamilyrequest) | [ImportFamilyResponse](#importfamilyresponse) | | | ImportUpdateFamily | [ImportUpdateFamilyRequest](#importupdatefamilyrequest) | [ImportUpdateFamilyResponse](#importupdatefamilyresponse) | | | ExportFamily | [ExportFamilyRequest](#exportfamilyrequest) | [ExportFamilyResponse](#exportfamilyresponse) | | | ValidateFamilyName | [ValidateFamilyNameRequest](#validatefamilynamerequest) | [ValidateFamilyNameResponse](#validatefamilynameresponse) | | | ValidateFamilyClientKey | [ValidateFamilyClientKeyRequest](#validatefamilyclientkeyrequest) | [ValidateFamilyClientKeyResponse](#validatefamilyclientkeyresponse) | | | GetFamilyStat | [GetFamilyStatRequest](#getfamilystatrequest) | [GetFamilyStatResponse](#getfamilystatresponse) | | | GetFamilyStats | [GetFamilyStatsRequest](#getfamilystatsrequest) | [GetFamilyStatsResponse](#getfamilystatsresponse) | | | CreateFamilyStatRanges | [CreateFamilyStatRangesRequest](#createfamilystatrangesrequest) | [CreateFamilyStatRangesResponse](#createfamilystatrangesresponse) | | | GetFamilyRuleDependencies | [GetFamilyRuleDependenciesRequest](#getfamilyruledependenciesrequest) | [GetFamilyRuleDependenciesResponse](#getfamilyruledependenciesresponse) | | | GenerateFamilyStatRangeName | [GenerateFamilyStatRangeNameRequest](#generatefamilystatrangenamerequest) | [GenerateFamilyStatRangeNameResponse](#generatefamilystatrangenameresponse) | | ## Messages *Data models used across requests/responses.* ### AbstractWindowType AbstractWindowType represents a window boundary that is agnostic of the alignment ID. | Field | Type | Label | Description | | :---------------------- | :----------------------- | :---- | :---------------------------------------------------------------------------------- | | family\_alignment\_name | string | | | | duration | google.protobuf.Duration | | Duration relative to the alignment used to compare the data. Defaults to 0 seconds. | ### AnnotationAlignment | Field | Type | Label | Description | | :------------- | :-------------------------------- | :---- | :---------- | | annotation\_id | string | | | | bound | [TimeRangeBound](#timerangebound) | | | ### CreateFamilyRequest | Field | Type | Label | Description | | :----------------- | :-------------------------------------- | :------- | :-------------------------------------------------------------------------------------------------------------------- | | family | [Family](#family) | | Family level information about the family such as archival status and client\_key are set in the Family. | | family\_version | [FamilyVersion](#familyversion) | | Version specific information about the family such as name, description, metadata, etc. are set in the FamilyVersion. | | family\_runs | [FamilyRun](#familyrun) | repeated | The runs to include in the family. At least one run must be specified. | | family\_alignments | [FamilyAlignment](#familyalignment) | repeated | The alignments to apply to the family. If not provided, a default alignment will be created for the Family. | | family\_stats | [FamilyStatDetails](#familystatdetails) | repeated | The family stats to create for the family. If not provided, no family stats will be created. | ### CreateFamilyResponse | Field | Type | Label | Description | | :--------- | :------------------------------ | :---- | :---------- | | family\_id | string | | | | family | [FamilyDetails](#familydetails) | | | ### CreateFamilyStatRangesRequest | Field | Type | Label | Description | | :------------------- | :---------------------------------- | :------- | :---------- | | family\_stat\_ids | string | repeated | | | family\_stat\_ranges | [FamilyStatRange](#familystatrange) | repeated | | ### CreateFamilyStatRangesResponse | Field | Type | Label | Description | | :------------------ | :-------------------------------------- | :------- | :---------- | | family\_version\_id | string | | | | family | [FamilyDetails](#familydetails) | | | | family\_stats | [FamilyStatDetails](#familystatdetails) | repeated | | ### DefaultAnnotationAlignment | Field | Type | Label | Description | | :---------------- | :-------------------------------------------- | :---- | :------------------------------------------------------------------------------------------------------------------------- | | annotation\_name | string | | | | bound | [TimeRangeBound](#timerangebound) | | | | occurrence | [AnnotationOccurrence](#annotationoccurrence) | | | | occurrence\_index | int32 | | Index of the annotation to use when occurrence is "nth". Positive indices start from the beginning, negative from the end. | ### ExportFamilyRequest | Field | Type | Label | Description | | :-------------------------------------------- | :----- | :---- | :---------- | | oneof family\_identifier. family\_id | string | | | | oneof family\_identifier. client\_key | string | | | | oneof family\_identifier. family\_version\_id | string | | | ### ExportFamilyResponse | Field | Type | Label | Description | | :--------------- | :----- | :---- | :---------- | | exported\_family | string | | | ### Family | Field | Type | Label | Description | | :--------------------- | :------------------------ | :---- | :------------------------------------------------------------- | | family\_id | string | | | | client\_key | string | | Client key is a user-provided unique identifier for the family | | current\_version\_id | string | | The latest family\_version\_id for the family. | | is\_archived | bool | | Whether the family is archived. | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | archived\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | organization\_id | string | | | ### FamilyAlignment FamilyAlignment represents a family-level time-alignment for naming and resolving run relative times. | Field | Type | Label | Description | | :----------------------------------- | :-------------------------------------------------------- | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | family\_alignment\_id | string | | When creating a family, this field can contain a temporary identifier provided by the client for referencing this alignment in family\_stats. The temporary ID must be unique within the CreateFamilyRequest and is required when this alignment is referenced in family\_stats. The service will resolve it to the actual alignment ID. When updating a family, this field must contain the actual family\_alignment\_id. In responses, this field contains the actual family\_alignment\_id. | | family\_version\_id | string | | | | name | string | | The name of the alignment. Must be unique within the family. | | description | string | | | | oneof default\_alignment. run | [RunAlignment](#runalignment) | | | | oneof default\_alignment. annotation | [DefaultAnnotationAlignment](#defaultannotationalignment) | | | | oneof default\_alignment. timestamp | [TimestampAlignment](#timestampalignment) | | | | family\_alignment\_points | [FamilyAlignmentPoint](#familyalignmentpoint) | repeated | Specific alignment points for each family member for the alignment. If not provided for a family member, the member does not implement this alignment. | ### FamilyAlignmentPoint FamilyAlignmentPoint represents a member specific time-alignment for the FamilyAlignment. | Field | Type | Label | Description | | :--------------------------- | :------------------------------------------ | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | family\_alignment\_point\_id | string | | When creating a family, this field can contain a temporary identifier provided by the client for referencing this alignment point in family\_stats. The temporary ID must be unique within the CreateFamilyRequest and is required when this alignment point is referenced in family\_stats. The service will resolve it to the actual alignment\_point\_id. When updating a family, this field must contain the actual family\_alignment\_point\_id. In responses, this field contains the actual family\_alignment\_point\_id. Can be empty string if not referenced in family\_stats. | | family\_run\_id | string | | | | run\_id | string | | | | family\_alignment\_id | string | | | | oneof alignment. run | [RunAlignment](#runalignment) | | | | oneof alignment. annotation | [AnnotationAlignment](#annotationalignment) | | | | oneof alignment. timestamp | [TimestampAlignment](#timestampalignment) | | | ### FamilyDetails | Field | Type | Label | Description | | :----------------- | :-------------------------------------- | :------- | :-------------------------------------------------------------------------------------------------------------- | | family | [Family](#family) | | | | family\_version | [FamilyVersion](#familyversion) | | The requested FamilyVersion for the family. Matches the current version unless a specific version is requested. | | family\_runs | [FamilyRun](#familyrun) | repeated | The family members associated with the FamilyVersion. | | family\_alignments | [FamilyAlignment](#familyalignment) | repeated | The alignments associated with the FamilyVersion. | | family\_stats | [FamilyStatDetails](#familystatdetails) | repeated | The family stats associated with the FamilyVersion. | ### FamilyRuleDependency | Field | Type | Label | Description | | :-------------- | :---------------------------------------------------------------------- | :---- | :---------- | | rule\_id | string | | | | name | string | | | | stat\_reference | [sift.rules.v1.FamilyStatReference](#sift-rules-v1-familystatreference) | | | ### FamilyRun FamilyRun represents a run which is either included in the family or explicitly excluded. | Field | Type | Label | Description | | :--------------------- | :------------------------ | :---- | :--------------------------------------------------------------------------------------------------------------- | | family\_run\_id | string | | | | family\_version\_id | string | | | | run\_id | string | | | | is\_exclusion | bool | | Whether the run is excluded from the family. If `true` the run is explicitly excluded, otherwise it is included. | | rationale | string | | User rationale for the inclusion or exclusion. | | added\_date | google.protobuf.Timestamp | | Date when the run was included or excluded from the family. | | added\_by\_user\_id | string | | User id of the user who included or excluded the run from the family. | | added\_in\_version\_id | string | | Version id of the version in which the run was included or excluded from the family. | ### FamilyStat | Field | Type | Label | Description | | :---------------------- | :------------------------ | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | family\_stat\_id | string | | | | family\_version\_id | string | | The family version id of the family stat. | | name | string | | The name of the family stat. | | description | string | | The description of the family stat. | | sample\_rate | double | | The sample rate of the family stat (Hz). | | default\_channel\_names | string | repeated | Ordered list of channel names to include in the family stat. The first channel name is the primary channel name across all the family members. The remaining channel names are fallback channels or individual overrides when the primary channel is not available across all the family members. | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | organization\_id | string | | | ### FamilyStatChannel | Field | Type | Label | Description | | :------------------------ | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | family\_stat\_channel\_id | string | | | | family\_stat\_id | string | | | | channel\_id | string | | The channel id of the channel to include in the family stat given the list of channel names provided in the family stat. | | alignment\_point\_id | string | | Specific alignment point id of the family member / channel to include in the family stat. When creating a family stat with a new Family, this field should contain the temporary\_id from FamilyAlignmentPoint.family\_alignment\_point\_id. The service will resolve it to the actual alignment\_point\_id. When updating a family stat, this field must contain the actual alignment\_point\_id. This will be prevalent when multiple alignment points are supported for a given family member. | ### FamilyStatDetails | Field | Type | Label | Description | | :------------------------ | :-------------------------------------------- | :------- | :---------- | | family\_stat | [FamilyStat](#familystat) | | | | family\_stat\_expressions | [FamilyStatExpression](#familystatexpression) | repeated | | | family\_stat\_channels | [FamilyStatChannel](#familystatchannel) | repeated | | | family\_stat\_ranges | [FamilyStatRange](#familystatrange) | repeated | | ### FamilyStatExpression | Field | Type | Label | Description | | :----------------------------- | :-------------------- | :---- | :---------- | | family\_stat\_expression\_id | string | | | | family\_stat\_id | string | | | | oneof expression. avg | google.protobuf.Empty | | | | oneof expression. median | google.protobuf.Empty | | | | oneof expression. min | google.protobuf.Empty | | | | oneof expression. max | google.protobuf.Empty | | | | oneof expression. stdev | google.protobuf.Empty | | | | oneof expression. sum | google.protobuf.Empty | | | | oneof expression. input\_count | google.protobuf.Empty | | | | oneof expression. sigma | google.protobuf.Empty | | | ### FamilyStatRange | Field | Type | Label | Description | | :---------------------- | :------------------------ | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | family\_stat\_range\_id | string | | | | family\_stat\_id | string | | | | family\_alignment\_id | string | | T-0 Alignment ID to align the data for stat calculation. When creating a family stat with a new Family, this field should contain the temporary\_id from FamilyAlignment.family\_alignment\_id. The service will resolve it to the actual alignment ID. When updating a family stat, this field must contain the actual family\_alignment\_id. | | name | string | | Unique name for the family stat range. | | window\_start | [WindowType](#windowtype) | optional | The start of the window for the stat calculation. The start is an alignment ID and a duration relative to the alignment. Defaults to T-0 alignment and 0 seconds. | | window\_end | [WindowType](#windowtype) | optional | The end of the window for the stat calculation. The end is an alignment ID and a duration relative to the alignment. Defaults to T-0 alignment and 0 seconds. However, window end must be after window start. Service provides basic validation: if window\_start.family\_alignment\_id = window\_end.family\_alignment\_id, then window\_start.duration \< window\_end.duration. | ### FamilyVersion | Field | Type | Label | Description | | :--------------------- | :---------------------------------------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | family\_version\_id | string | | | | family\_id | string | | | | version | uint32 | | | | name | string | | The name of the family. Must be unique within the organization for the latest family versions. | | description | string | | | | run\_query | string | | An optional query to track a CEL expression against the ListRuns endpoint. This query is only for reference, and does not affect the runs that are included in the family. To specify which runs are included in the family, use the `runs` field. | | user\_notes | string | | Notes provided by the user to describe the family version changes | | change\_message | string | | Family Service provided message describing the changes made to the family version. | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | Metadata associated with the family version. | | sigma\_default\_values | double | repeated | User-configurable default sigma multiplier values, e.g. \[1, 2, 3]. If not provided, the default values \[-1, 1, -2, 2, -3, 3] will be used. | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | organization\_id | string | | | ### GenerateFamilyStatRangeNameRequest | Field | Type | Label | Description | | :---------------------- | :---------------------------------------- | :---- | :---------- | | family\_alignment\_name | string | | | | window\_start | [AbstractWindowType](#abstractwindowtype) | | | | window\_end | [AbstractWindowType](#abstractwindowtype) | | | ### GenerateFamilyStatRangeNameResponse | Field | Type | Label | Description | | :---- | :----- | :---- | :---------- | | name | string | | | ### GetFamiliesRequest | Field | Type | Label | Description | | :----------- | :----- | :------- | :---------- | | family\_ids | string | repeated | | | client\_keys | string | repeated | | ### GetFamiliesResponse | Field | Type | Label | Description | | :------- | :------------------------------ | :------- | :---------- | | families | [FamilyDetails](#familydetails) | repeated | | ### GetFamilyCandidateRunCountRequest | Field | Type | Label | Description | | :------------------ | :----- | :---- | :---------- | | family\_version\_id | string | | | ### GetFamilyCandidateRunCountResponse | Field | Type | Label | Description | | :---- | :----- | :---- | :---------- | | count | uint32 | | | ### GetFamilyCandidateRunsRequest | Field | Type | Label | Description | | :------------------ | :----- | :---- | :---------- | | family\_version\_id | string | | | ### GetFamilyCandidateRunsResponse | Field | Type | Label | Description | | :------------------ | :----- | :------- | :---------- | | run\_query | string | | | | candidate\_run\_ids | string | repeated | | ### GetFamilyRequest | Field | Type | Label | Description | | :------------------------------------ | :----- | :---- | :---------- | | oneof family\_identifier. family\_id | string | | | | oneof family\_identifier. client\_key | string | | | ### GetFamilyResponse | Field | Type | Label | Description | | :----- | :------------------------------ | :---- | :---------- | | family | [FamilyDetails](#familydetails) | | | ### GetFamilyRuleDependenciesRequest | Field | Type | Label | Description | | :--------- | :----- | :---- | :---------- | | family\_id | string | | | ### GetFamilyRuleDependenciesResponse | Field | Type | Label | Description | | :----------------- | :-------------------------------------------- | :------- | :---------- | | rule\_dependencies | [FamilyRuleDependency](#familyruledependency) | repeated | | ### GetFamilyStatRequest | Field | Type | Label | Description | | :--------------- | :----- | :---- | :---------- | | family\_stat\_id | string | | | ### GetFamilyStatResponse | Field | Type | Label | Description | | :-------------------- | :-------------------------------------- | :---- | :---------- | | family\_stat\_details | [FamilyStatDetails](#familystatdetails) | | | ### GetFamilyStatsRequest | Field | Type | Label | Description | | :------------------ | :----- | :---- | :---------- | | family\_version\_id | string | | | ### GetFamilyStatsResponse | Field | Type | Label | Description | | :--------------------- | :-------------------------------------- | :------- | :---------- | | family\_stats\_details | [FamilyStatDetails](#familystatdetails) | repeated | | ### GetFamilyVersionRequest | Field | Type | Label | Description | | :------------------ | :----- | :---- | :---------- | | family\_version\_id | string | | | ### GetFamilyVersionResponse | Field | Type | Label | Description | | :----- | :------------------------------ | :---- | :---------- | | family | [FamilyDetails](#familydetails) | | | ### ImportFamilyRequest | Field | Type | Label | Description | | :----------- | :----- | :---- | :---------------------------------------------------------------------------------------------------------------------------------------- | | family\_yaml | string | | The source to import the family from. Must provide family\_yaml. The contents of the source should match the shape of CreateFamilyRequest | ### ImportFamilyResponse | Field | Type | Label | Description | | :--------- | :------------------------------ | :---- | :---------- | | family\_id | string | | | | family | [FamilyDetails](#familydetails) | | | ### ImportUpdateFamilyRequest | Field | Type | Label | Description | | :------------------------------------ | :------------------------------------------------------ | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | oneof family\_identifier. family\_id | string | | | | oneof family\_identifier. client\_key | string | | | | family\_yaml | string | | The source to update the family from. Must provide family\_yaml. The contents of the source should match the shape of UpdateFamilyRequest FamilyDetails. The update\_mask is optional and defaults to updating provided fields. | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | See UpdateFamilyRequest | ### ImportUpdateFamilyResponse | Field | Type | Label | Description | | :------------------ | :------------------------------ | :---- | :---------- | | family\_version\_id | string | | | | family | [FamilyDetails](#familydetails) | | | ### ListFamiliesRequest | Field | Type | Label | Description | | :---------- | :----- | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of families to return. The service may return fewer than this value, even if there are additional pages. If unspecified, the limit defaults to 50. The maximum value is 100. | | page\_token | string | | A page token, received from a previous `ListFamilies` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListFamilies` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are: `family_id`, `client_key`, `organization_id`, `archived_date`, `is_archived`, `created_by_user_id`, `created_date`, `modified_by_user_id`, `modified_date`, `name`, `description`, `run_query`, `run_id_includes`, `run_id_excludes`, `alignment_name`, `alignment_description`, `metadata`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved families. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are: `created_date`, `modified_date`, `archived_date`. If left empty, items are ordered by `created_date` in descending order. For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc" | ### ListFamiliesResponse | Field | Type | Label | Description | | :---------------- | :------------------------ | :------- | :----------------------------------------------------------------------------------------------------------------------------- | | families | [ListFamily](#listfamily) | repeated | | | next\_page\_token | string | | A token, which can be sent as `page_token` to retrieve the next page. If this field is omitted, there are no subsequent pages. | ### ListFamily | Field | Type | Label | Description | | :-------------- | :------------------------------ | :---- | :---------------------------------------------------- | | family | [Family](#family) | | | | family\_version | [FamilyVersion](#familyversion) | | The latest family version associated with the Family. | ### ListFamilyAlignmentPointsRequest | Field | Type | Label | Description | | :-------------------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | family\_alignment\_id | string | | Provide family\_alignment\_id to identify the family to list alignments points. | | page\_size | uint32 | | The maximum number of family version alignment points to return. The service may return fewer than this value, even if there are additional pages. If unspecified, the limit defaults to 200. The maximum value is 1000. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are: `family_run_id`, and for the associated Run: `name`, `description`, `start_time`, `end_time`, `duration`. Note: `name`, `description`, `start_time`, `end_time`, and `duration` are filters on the associated run. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | page\_token | string | | A page token, received from a previous `ListFamilyAlignmentPoints` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListFamilyAlignmentPoints` must match the call that provided the page token. | ### ListFamilyAlignmentPointsResponse | Field | Type | Label | Description | | :------------------------ | :-------------------------------------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------- | | family\_alignment\_points | [FamilyAlignmentPoint](#familyalignmentpoint) | repeated | | | next\_page\_token | string | | A token, which can be sent as `page_token` to retrieve the next page. If this field is omitted, there are no subsequent pages. | ### ListFamilyAlignmentsRequest | Field | Type | Label | Description | | :------------------ | :----- | :---- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | family\_version\_id | string | | Provide family\_id to identify the family to list alignments. | | page\_size | uint32 | | The maximum number of family version alignments to return. The service may return fewer than this value, even if there are additional pages. If unspecified, the limit defaults to 200. The maximum value is 1000. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are: `name`, `description`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | page\_token | string | | A page token, received from a previous `ListFamilyAlignments` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListFamilyAlignments` must match the call that provided the page token. | ### ListFamilyAlignmentsResponse | Field | Type | Label | Description | | :----------------- | :---------------------------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------- | | family\_alignments | [FamilyAlignment](#familyalignment) | repeated | | | next\_page\_token | string | | A token, which can be sent as `page_token` to retrieve the next page. If this field is omitted, there are no subsequent pages. | ### ListFamilyCandidateRunsRequest Request for `FamilyService.ListFamilyCandidateRuns`. The CEL filter supports the standard run filter fields plus an `include_archived` directive. Archived runs are excluded by default; pass `include_archived == true` in the filter to include them. When `family_id` is set, the server filters out runs already on that family's persisted membership (both included and excluded entries) so the response only contains runs not yet on the family. Clients editing an unsaved draft of family membership should omit `family_id` and apply their own draft-aware filtering, since the persisted membership does not reflect the draft state. | Field | Type | Label | Description | | :---------- | :----- | :---- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of runs to return. The service may return fewer than this value. If unspecified, at most 50 runs will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. | | page\_token | string | | A page token, received from a previous call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Supports all ListRuns filter fields plus `include_archived`. When `include_archived` is not present in the filter, archived runs are excluded by default. Set `include_archived == true` in the filter to include archived runs. Note: `include_archived` is a directive and must appear at the top level of the filter (or within a top-level AND chain). It cannot be used inside an OR expression. | | order\_by | string | | How to order the retrieved runs. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `name`, `description`, `created_date`, `modified_date`, `start_time`, and `stop_time`. If left empty, items are ordered by `created_date` in descending order (newest-first). | | family\_id | string | | Optional family ID to filter out runs already on the family's persisted membership. When set, the response excludes runs that are already included or excluded in the family. Omit this field when working with draft membership changes. | ### ListFamilyCandidateRunsResponse | Field | Type | Label | Description | | :---------------- | :------------------------------------ | :------- | :---------- | | runs | [sift.runs.v2.Run](#sift-runs-v2-run) | repeated | | | next\_page\_token | string | | | ### ListFamilyMembersRequest | Field | Type | Label | Description | | :------------------ | :----- | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | family\_version\_id | string | | Provide family\_version\_id to identify the family to list members for. | | page\_size | uint32 | | The maximum number of family members to return. The service may return fewer than this value, even if there are additional pages. If unspecified, the max limit defaults to 200. The maximum value is 500. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are: `is_exclusion`, `rationale`, `added_date`, `added_by_user_id`, `added_in_version_id`, and for the associated Run:`name`, `description`, `start_time`, `end_time`, `duration`. Note: `name`, `description`, `start_time`, `end_time`, and `duration` are filters on the associated run. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | page\_token | string | | A page token, received from a previous `ListFamilyMembers` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListFamilyMembers` must match the call that provided the page token. | ### ListFamilyMembersResponse | Field | Type | Label | Description | | :---------------- | :---------------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------- | | family\_runs | [FamilyRun](#familyrun) | repeated | | | next\_page\_token | string | | A token, which can be sent as `page_token` to retrieve the next page. If this field is omitted, there are no subsequent pages. | ### ListFamilyVersionsRequest | Field | Type | Label | Description | | :---------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | page\_size | uint32 | | The maximum number of family versions to return. The service may return fewer than this value, even if there are additional pages. If unspecified, the max limit defaults to 50. The maximum value is 200. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are: `family_id`, `family_version_id`, `organization_id`, `name`, `description`, `run_query`, `user_notes`, `change_message`, `created_by_user_id`, `created_date`, `modified_by_user_id`, `modified_date`, `archived_date`, `is_archived`, `run_id_includes`, `run_id_excludes`, `alignment_name`, `alignment_description`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | page\_token | string | | A page token, received from a previous `ListFamilyVersions` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListFamilyVersions` must match the call that provided the page token. | | order\_by | string | | How to order the retrieved family versions. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are: `created_date`, `modified_date`, `name`. If left empty, items are ordered by `created_date` in descending order. For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc" | ### ListFamilyVersionsResponse | Field | Type | Label | Description | | :---------------- | :------------------------------ | :------- | :----------------------------------------------------------------------------------------------------------------------------- | | family\_versions | [FamilyVersion](#familyversion) | repeated | | | next\_page\_token | string | | A token, which can be sent as `page_token` to retrieve the next page. If this field is omitted, there are no subsequent pages. | ### RunAlignment | Field | Type | Label | Description | | :---- | :-------------------------------- | :---- | :---------- | | bound | [TimeRangeBound](#timerangebound) | | | ### TimestampAlignment | Field | Type | Label | Description | | :-------- | :------------------------ | :---- | :---------- | | timestamp | google.protobuf.Timestamp | | | ### UpdateFamilyRequest | Field | Type | Label | Description | | :------------------------------------ | :------------------------------------------------------ | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | oneof family\_identifier. family\_id | string | | | | oneof family\_identifier. client\_key | string | | | | family | [FamilyDetails](#familydetails) | | The family data to update. Only fields referenced in the update\_mask will be updated. | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | Note: Whenever the family is updated, the family stats are also updated to point to the new family version to ensure the family stats are always up to date. client\_key can only be updated if it is not already set. It must be passed in via the family request and cannot be used as identifier. | ### UpdateFamilyResponse | Field | Type | Label | Description | | :------------------ | :-------------------------------------- | :------- | :---------- | | family\_version\_id | string | | | | family | [FamilyDetails](#familydetails) | | | | family\_stats | [FamilyStatDetails](#familystatdetails) | repeated | | ### ValidateFamilyClientKeyRequest | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------- | | client\_key | string | | | ### ValidateFamilyClientKeyResponse | Field | Type | Label | Description | | :--------------------------- | :----- | :---- | :---------- | | oneof result. success | bool | | | | oneof result. error\_message | string | | | ### ValidateFamilyNameRequest | Field | Type | Label | Description | | :----------- | :----- | :---- | :---------- | | family\_name | string | | | ### ValidateFamilyNameResponse | Field | Type | Label | Description | | :--------------------------- | :----- | :---- | :---------- | | oneof result. success | bool | | | | oneof result. error\_message | string | | | ### WindowType WindowType represents a window boundary that can be either an alignment ID or a duration. | Field | Type | Label | Description | | :-------------------- | :----------------------- | :---- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | family\_alignment\_id | string | | Alignment ID to use as the window boundary. When creating a family stat with a new Family, this field should contain the temporary\_id from FamilyAlignment.family\_alignment\_id. Default to the window's T-0 alignment. The service will resolve it to the actual alignment ID. When updating a family stat, this field must contain the actual family\_alignment\_id. | | duration | google.protobuf.Duration | | Duration relative to the alignment used to compare the data. Defaults to 0 seconds. | ## Enums *Allowed constant values used in message fields.* ### AnnotationOccurrence | Name | Number | Description | | :---------------------------------- | :----- | :-------------- | | ANNOTATION\_OCCURRENCE\_UNSPECIFIED | 0 | **Deprecated.** | | ANNOTATION\_OCCURRENCE\_FIRST | 1 | | | ANNOTATION\_OCCURRENCE\_LAST | 2 | | | ANNOTATION\_OCCURRENCE\_EVERY | 3 | | | ANNOTATION\_OCCURRENCE\_NTH | 4 | | ### TimeRangeBound | Name | Number | Description | | :------------------------------ | :----- | :-------------- | | TIME\_RANGE\_BOUND\_UNSPECIFIED | 0 | **Deprecated.** | | TIME\_RANGE\_BOUND\_START | 1 | | | TIME\_RANGE\_BOUND\_END | 2 | | # gRPC Source: https://docs.siftstack.com/api/reference/protocol-buffers/index Use Sift's gRPC API with official client libraries or grpcurl. Sift's gRPC API handles high-frequency telemetry ingestion and real-time analysis. It uses Protocol Buffers to define services and messages for efficient, high-throughput communication. You can interact with it in multiple ways: * Directly using standard tools like [`grpcurl`](https://github.com/fullstorydev/grpcurl) or by writing your own gRPC clients. * Using Sift's pre-built client libraries, available for select programming languages to simplify setup. Client libraries use [gRPC interceptors](https://grpc.io/docs/guides/interceptors/) to automate authentication and request handling. To authenticate a request directly, see [Authenticate with the API](/api/authenticate/authenticate-with-the-api). ## Listing services from the command line You can use [`grpcurl`](https://github.com/fullstorydev/grpcurl) to explore Sift's available gRPC services directly from the command line. ```bash theme={null} grpcurl $SIFT_GRPC_BASE_URL:$PORT_NUM list ``` ```bash theme={null} grpcurl $SIFT_GRPC_BASE_URL:$PORT_NUM list sift.assets.v1.AssetService ``` **gRPC base URL and port:** Do not include `https://` in the base URL, use only the hostname. `$PORT_NUM` is always `443`. ## Official client libraries Sift provides pre-built client libraries for Python, Rust, and Go, maintained as open source in the [Sift GitHub repository](https://github.com/sift-stack/sift). These libraries use the gRPC API internally. Supported languages: * [Python](#python) * [Rust](#rust) * [Go](#go) ### Other languages If your preferred language doesn't yet have a dedicated client library, you can instead: * [Generate a client with Buf](/api/clients/generate-a-client-with-buf) to compile Sift's Protocol Buffers into gRPC client code for your preferred language. * Use the [Sift REST API](/api/overview#choosing-between-rest-and-grpc), a standard HTTP-based interface for integration. ### URL formatting for official gRPC clients The required format for official gRPC API URLs depends on your client library. Some libraries require you to omit the URL scheme and port number, while others expect them to be included. Refer to the documentation of your chosen client library to confirm the expected URL format. **Port:** The gRPC API uses port `443` by default in all environments. ## Connect with an official client ### Python 1. Create a Python environment. ```bash theme={null} python3 -m venv venv ``` 2. In your Python environment (`venv`) install the [Sift Python package](https://pypi.org/project/sift-stack-py/): ```bash theme={null} pip install sift-stack-py ``` 3. In your Python environment directory, create a file named `main.py` and paste the following code: ```python theme={null} import os from sift.ping.v1.ping_pb2 import PingRequest from sift.ping.v1.ping_pb2_grpc import PingServiceStub from sift_py.grpc.transport import SiftChannelConfig, use_sift_channel if __name__ == "__main__": apikey = os.getenv("SIFT_API_KEY") assert apikey uri = os.getenv("SIFT_GRPC_BASE_URL") assert uri channel_config: SiftChannelConfig = { "apikey": apikey, "uri": uri, } with use_sift_channel(channel_config) as channel: response = PingServiceStub(channel).Ping(PingRequest()) print(response) ``` 4. In your Python environment directory, run the following command after replacing the placeholders (`$SIFT_API_KEY` and `$SIFT_GRPC_BASE_URL`) with your actual values: ```bash theme={null} SIFT_GRPC_BASE_URL=$SIFT_GRPC_BASE_URL:$PORT_NUM SIFT_API_KEY=$SIFT_API_KEY python main.py ``` See the [Python client documentation](https://sift-stack.github.io/sift/python/latest/) for the full API reference. ### Rust 1. Create a Rust project. ```bash theme={null} cargo new my_sift_project ``` 2. In your Rust project, add the [`sift_rs`](https://crates.io/crates/sift_rs) crate. ```bash theme={null} cd my_sift_project cargo add sift_rs ``` 3. In your Rust project, add the `tokio` runtime. ```bash theme={null} cargo add tokio --features full ``` 4. Copy and paste the following into your `my_sift_project/src/main.rs`: ```bash theme={null} use sift_rs::{ Credentials, SiftChannelBuilder, ping::v1::{PingRequest, ping_service_client::PingServiceClient}, }; use std::env; #[tokio::main] async fn main() { let credentials = Credentials::Config { apikey: env::var("SIFT_API_KEY").unwrap(), uri: env::var("SIFT_GRPC_BASE_URL").unwrap(), }; let conn = SiftChannelBuilder::new(credentials).build().unwrap(); let mut ping_service = PingServiceClient::new(conn); let ping_response = ping_service.ping(PingRequest::default()).await.unwrap(); println!("{}", ping_response.into_inner().response); } ``` 5. In your Rust project directory, run the following command after replacing the placeholders (`$SIFT_API_KEY` and `$SIFT_GRPC_BASE_URL`) with your actual values: ```bash theme={null} SIFT_GRPC_BASE_URL=$SIFT_GRPC_BASE_URL:$PORT_NUM SIFT_API_KEY=$SIFT_API_KEY cargo run ``` ### Go 1. Set up a dedicated directory and initialize it as a Go module using `go mod`: ```bash theme={null} mkdir go-client-connection && cd go-client-connection go mod init sift_go_project ``` 2. Use `go get` to fetch the [Sift Go SDK](https://pkg.go.dev/github.com/sift-stack/sift/go) and include it in your project: ```bash theme={null} go get github.com/sift-stack/sift/go ``` 3. In the `sift_go_project` directory, create a `main.go` file and copy and paste the following into that file: ```bash theme={null} package main import ( "context" "fmt" "log" "os" "github.com/sift-stack/sift/go/gen/sift/ping/v1" "github.com/sift-stack/sift/go/grpc" ) func main() { ctx := context.Background() channelConfig := grpc.SiftChannelConfig{ Uri: os.Getenv("SIFT_GRPC_BASE_URL"), Apikey: os.Getenv("SIFT_API_KEY"), } conn, err := grpc.UseSiftChannel(ctx, channelConfig) if err != nil { log.Fatalln(err) } pingClient := pingv1.NewPingServiceClient(conn) res, err := pingClient.Ping(ctx, &pingv1.PingRequest{}) if err != nil { log.Fatalln(err) } fmt.Println(res.Response) } ``` 4. Verify and tidy up your module dependencies: ```bash theme={null} go mod tidy ``` 5. In your Go module, run the following command after replacing the placeholders (`$SIFT_API_KEY`, `$SIFT_GRPC_BASE_URL`, and `$PORT_NUM`) with your actual values: ```bash theme={null} SIFT_GRPC_BASE_URL=$SIFT_GRPC_BASE_URL:$PORT_NUM SIFT_API_KEY=$SIFT_API_KEY go run . ``` # ingest Source: https://docs.siftstack.com/api/reference/protocol-buffers/ingest sift/ingest/v1/ingest.proto ## Services *RPC methods exposed by this API.* ### IngestService | Method | Request | Response | Description | | :-------------------------------- | :----------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------- | :---------- | | IngestWithConfigDataStream | [IngestWithConfigDataStreamRequest](#ingestwithconfigdatastreamrequest) *(stream)* | [IngestWithConfigDataStreamResponse](#ingestwithconfigdatastreamresponse) | | | IngestArbitraryProtobufDataStream | [IngestArbitraryProtobufDataStreamRequest](#ingestarbitraryprotobufdatastreamrequest) *(stream)* | [IngestArbitraryProtobufDataStreamResponse](#ingestarbitraryprotobufdatastreamresponse) | | ## Messages *Data models used across requests/responses.* ### IngestArbitraryProtobufDataStreamRequest | Field | Type | Label | Description | | :--------------------------------- | :------------------------ | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | message\_type\_identifier | string | | | | message\_type\_display\_name | string | optional | | | asset\_name | string | | | | timestamp | google.protobuf.Timestamp | | | | value | bytes | | | | run\_id | string | | | | namespace | string | | | | organization\_id | string | | | | end\_stream\_on\_validation\_error | bool | | By default, if this request fails to parse for any reason, the request is stored in an error queue and the stream continues to accept data. This ensures all data is saved, but only valid data is fully ingested. If this is set to `true`, any validation errors end the stream and return the error to the client. | ### IngestArbitraryProtobufDataStreamResponse *This message has no fields.* ### IngestWithConfigDataChannelValue | Field | Type | Label | Description | | :--------------------- | :-------------------- | :---- | :------------------------------------------------------------------------------------------ | | oneof type. string | string | | | | oneof type. double | double | | | | oneof type. float | float | | | | oneof type. bool | bool | | | | oneof type. int32 | int32 | | | | oneof type. uint32 | uint32 | | | | oneof type. int64 | int64 | | | | oneof type. uint64 | uint64 | | | | oneof type. bit\_field | bytes | | | | oneof type. enum | uint32 | | | | oneof type. empty | google.protobuf.Empty | | If there's not a new data point for a channel at the given timestamp, pass empty to skip it | | oneof type. bytes | bytes | | | ### IngestWithConfigDataStreamRequest INTERNAL NOTE (remove from public protos): Any updates to this proto message MUST also update the `IngestWithConfigDataStreamRequestLite` and `IngestWithConfigDataStreamChannelValuesOnly` proto messages in sift\_internal/ingest/v1/ingest.proto. For performance, only the minimal set of fields is deserialized on ingest by the `IngestWithConfigDataStreamRequestLite` proto message definition; other fields that are expensive and/or large and that are not required to be parsed should not be included there. Additionally, the field number **MUST** match exactly as we depend on the field numbers to correctly decode the fields despite technically different message definitions. | Field | Type | Label | Description | | :--------------------------------- | :-------------------------------------------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | ingestion\_config\_id | string | | | | flow | string | | | | timestamp | google.protobuf.Timestamp | | | | channel\_values | [IngestWithConfigDataChannelValue](#ingestwithconfigdatachannelvalue) | repeated | | | run\_id | string | | The run\_id MUST be included if this data is part of a run. | | end\_stream\_on\_validation\_error | bool | | By default, if this request contains any channel values that do not match the supplied ingestion config, the request is stored in an error queue and the stream continues to accept data. This ensures all data is saved, but only valid data is fully ingested. If this is set to `true`, any validation errors end the stream and return the error to the client. | | organization\_id | string | | | ### IngestWithConfigDataStreamResponse *This message has no fields.* ## Enums *Allowed constant values used in message fields.* # ingestion_configs Source: https://docs.siftstack.com/api/reference/protocol-buffers/ingestion_configs sift/ingestion_configs/v2/ingestion_configs.proto ## Services *RPC methods exposed by this API.* ### IngestionConfigService | Method | Request | Response | Description | | :------------------------- | :---------------------------------------------------------------------- | :------------------------------------------------------------------------ | :---------------------------------------------------- | | GetIngestionConfig | [GetIngestionConfigRequest](#getingestionconfigrequest) | [GetIngestionConfigResponse](#getingestionconfigresponse) | Retrieves an ingestion config. | | CreateIngestionConfig | [CreateIngestionConfigRequest](#createingestionconfigrequest) | [CreateIngestionConfigResponse](#createingestionconfigresponse) | Create an ingestion config. | | ListIngestionConfigs | [ListIngestionConfigsRequest](#listingestionconfigsrequest) | [ListIngestionConfigsResponse](#listingestionconfigsresponse) | List ingestion configs using an optional filter. | | CreateIngestionConfigFlows | [CreateIngestionConfigFlowsRequest](#createingestionconfigflowsrequest) | [CreateIngestionConfigFlowsResponse](#createingestionconfigflowsresponse) | Create ingestion config flows. | | ListIngestionConfigFlows | [ListIngestionConfigFlowsRequest](#listingestionconfigflowsrequest) | [ListIngestionConfigFlowsResponse](#listingestionconfigflowsresponse) | List ingestion config flows using an optional filter. | ## Messages *Data models used across requests/responses.* ### ChannelConfig | Field | Type | Label | Description | | :------------------- | :---------------------------------------------------------------------------------------- | :------- | :---------- | | name | string | | | | unit | string | | | | description | string | | | | data\_type | [sift.common.type.v1.ChannelDataType](#sift-common-type-v1-channeldatatype) | | | | enum\_types | [sift.common.type.v1.ChannelEnumType](#sift-common-type-v1-channelenumtype) | repeated | | | bit\_field\_elements | [sift.common.type.v1.ChannelBitFieldElement](#sift-common-type-v1-channelbitfieldelement) | repeated | | ### CreateIngestionConfigFlowsRequest The request for a call to `IngestionConfigService_CreateIngestionConfigFlows` to create ingestion config flows. | Field | Type | Label | Description | | :-------------------- | :------------------------ | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------- | | ingestion\_config\_id | string | | | | flows | [FlowConfig](#flowconfig) | repeated | These flows must have unique names. If you try to send a flow with a name that already exists for an ingestion config, it will return an error. | ### CreateIngestionConfigFlowsResponse The result of a call to `IngestionConfigService_CreateIngestionConfigFlows`. *This message has no fields.* ### CreateIngestionConfigRequest The request for a call to `IngestionConfigService_CreateIngestionConfig` to retrieve ingestion configs. | Field | Type | Label | Description | | :--------------- | :------------------------ | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | asset\_name | string | | | | flows | [FlowConfig](#flowconfig) | repeated | | | organization\_id | string | | | | client\_key | string | | The `client_key` field is a user-defined string you can supply to uniquely identify an ingestion config (and retrieve it via `GetIngestionConfig`). An error is returned if you try to create an ingestion config with a client\_key that already exists. | ### CreateIngestionConfigResponse The result of a call to `IngestionConfigService_CreateIngestionConfig`. | Field | Type | Label | Description | | :---------------- | :---------------------------------- | :---- | :---------- | | ingestion\_config | [IngestionConfig](#ingestionconfig) | | | ### FlowConfig | Field | Type | Label | Description | | :------- | :------------------------------ | :------- | :---------- | | name | string | | | | channels | [ChannelConfig](#channelconfig) | repeated | | ### GetIngestionConfigRequest The request for a call to `IngestionConfigService_GetIngestionConfig` to retrieve an ingestion config. | Field | Type | Label | Description | | :-------------------- | :----- | :---- | :---------- | | ingestion\_config\_id | string | | | ### GetIngestionConfigResponse The result of a call to `IngestionConfigService_GetIngestionConfig`. | Field | Type | Label | Description | | :---------------- | :---------------------------------- | :---- | :---------- | | ingestion\_config | [IngestionConfig](#ingestionconfig) | | | ### IngestionConfig | Field | Type | Label | Description | | :-------------------- | :----- | :---- | :---------- | | ingestion\_config\_id | string | | | | asset\_id | string | | | | client\_key | string | | | ### ListIngestionConfigFlowsRequest The request for a call to `IngestionConfigService_ListIngestionConfigFlows` to retrieve ingestion config flows. | Field | Type | Label | Description | | :-------------------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | ingestion\_config\_id | string | | | | page\_size | uint32 | | The maximum number of ingestion config flows to return. The service may return fewer than this value. If unspecified, at most 50 ingestion config flows will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListIngestionConfigFlows` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListIngestionConfigFlows` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `flow_name`, `flow_id`, `created_date`, and `modified_date`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | ### ListIngestionConfigFlowsResponse The result of a call to `IngestionConfigService_ListIngestionConfigFlows`. | Field | Type | Label | Description | | :---------------- | :------------------------ | :------- | :---------- | | flows | [FlowConfig](#flowconfig) | repeated | | | next\_page\_token | string | | | ### ListIngestionConfigsRequest The request for a call to `IngestionConfigService_ListIngestionConfigs` to retrieve ingestion configs. | Field | Type | Label | Description | | :---------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of ingestion configs to return. The service may return fewer than this value. If unspecified, at most 50 ingestion configs will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListIngestionConfigs` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListIngestionConfigs` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `ingestion_config_id`, `client_key`, `asset_id`, `created_date`, and `modified_date`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | ### ListIngestionConfigsResponse The result of a call to `IngestionConfigService_ListIngestionConfigs`. | Field | Type | Label | Description | | :----------------- | :---------------------------------- | :------- | :---------- | | ingestion\_configs | [IngestionConfig](#ingestionconfig) | repeated | | | next\_page\_token | string | | | ## Enums *Allowed constant values used in message fields.* # jobs Source: https://docs.siftstack.com/api/reference/protocol-buffers/jobs sift/jobs/v1/jobs.proto ## Services *RPC methods exposed by this API.* ### JobService | Method | Request | Response | Description | | :-------- | :------------------------------------ | :-------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ListJobs | [ListJobsRequest](#listjobsrequest) | [ListJobsResponse](#listjobsresponse) | List jobs. | | CancelJob | [CancelJobRequest](#canceljobrequest) | [CancelJobResponse](#canceljobresponse) | Requests cancellation of an active job. If the job hasn't started yet, it will be cancelled immediately. Jobs that are already finished, failed, or cancelled are not affected. Cancelled jobs have implementation-based behavior, but in every case it's valid to cancel a job at any time. | | RetryJob | [RetryJobRequest](#retryjobrequest) | [RetryJobResponse](#retryjobresponse) | Requests a retry of a job. Jobs that are finished, in progress or in the process of being cancelled are not affected. | ## Messages *Data models used across requests/responses.* ### CancelJobRequest | Field | Type | Label | Description | | :------ | :----- | :---- | :---------- | | job\_id | string | | | ### CancelJobResponse *This message has no fields.* ### DataExportJobDetails | Field | Type | Label | Description | | :----------- | :---------------------------------------------------------------------- | :---- | :---------- | | request | [sift.exports.v1.ExportDataRequest](#sift-exports-v1-exportdatarequest) | | | | storage\_key | string | | | ### DataExportStatusDetails | Field | Type | Label | Description | | :------------- | :----- | :---- | :---------- | | error\_message | string | | | ### DataImportJobDetails | Field | Type | Label | Description | | :--------------- | :----- | :---- | :---------- | | data\_import\_id | string | | | ### DataImportStatusDetails | Field | Type | Label | Description | | :---------------- | :----- | :---- | :---------- | | points\_processed | uint64 | | | | points\_total | uint64 | | | ### Job | Field | Type | Label | Description | | :--------------------- | :------------------------------------ | :---- | :---------- | | job\_id | string | | | | organization\_id | string | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | started\_date | google.protobuf.Timestamp | | | | completed\_date | google.protobuf.Timestamp | | | | job\_type | [JobType](#jobtype) | | | | job\_status | [JobStatus](#jobstatus) | | | | job\_status\_details | [JobStatusDetails](#jobstatusdetails) | | | | job\_details | [JobDetails](#jobdetails) | | | ### JobDetails | Field | Type | Label | Description | | :------------------------------ | :---------------------------------------------------- | :---- | :---------- | | oneof details. rule\_evaluation | [RuleEvaluationJobDetails](#ruleevaluationjobdetails) | | | | oneof details. data\_import | [DataImportJobDetails](#dataimportjobdetails) | | | | oneof details. data\_export | [DataExportJobDetails](#dataexportjobdetails) | | | ### JobStatusDetails | Field | Type | Label | Description | | :----------------------------- | :---------------------------------------------------------- | :---- | :---------- | | oneof status. rule\_evaluation | [RuleEvaluationStatusDetails](#ruleevaluationstatusdetails) | | | | oneof status. data\_import | [DataImportStatusDetails](#dataimportstatusdetails) | | | | oneof status. data\_export | [DataExportStatusDetails](#dataexportstatusdetails) | | | ### ListJobsRequest | Field | Type | Label | Description | | :--------------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | page\_size | uint32 | | The maximum number of jobs to return. The service may return fewer than this value. If unspecified, at most 50 jobs will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListJobs` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListJobs` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are: `job_id`, `created_by_user_id`, `modified_by_user_id`, `created_date`, `modified_date`, `started_date`, `completed_date`, and `job_status` For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). For more information about the fields used for filtering, please refer to this definition. Optional. | | organization\_id | string | | This field is only required if your user belongs to multiple organizations. | | order\_by | string | | How to order the retrieved jobs. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date`, `modified_date`, `started_date`, `completed_date`, `job_status`. If left empty, items are ordered by `created_date` in descending order (newest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | ### ListJobsResponse | Field | Type | Label | Description | | :---------------- | :---------- | :------- | :---------- | | jobs | [Job](#job) | repeated | | | next\_page\_token | string | | | ### RetryJobRequest | Field | Type | Label | Description | | :------ | :----- | :---- | :---------- | | job\_id | string | | | ### RetryJobResponse | Field | Type | Label | Description | | :---- | :---------- | :---- | :---------- | | job | [Job](#job) | | | ### RuleEvaluationJobDetails | Field | Type | Label | Description | | :--------- | :----- | :---- | :---------- | | report\_id | string | | | ### RuleEvaluationStatusDetails *This message has no fields.* ## Enums *Allowed constant values used in message fields.* ### JobStatus | Name | Number | Description | | :----------------------------- | :----- | :-------------- | | JOB\_STATUS\_UNSPECIFIED | 0 | **Deprecated.** | | JOB\_STATUS\_CREATED | 1 | | | JOB\_STATUS\_RUNNING | 2 | | | JOB\_STATUS\_FINISHED | 3 | | | JOB\_STATUS\_FAILED | 4 | | | JOB\_STATUS\_CANCELLED | 5 | | | JOB\_STATUS\_CANCEL\_REQUESTED | 6 | | ### JobType | Name | Number | Description | | :-------------------------- | :----- | :-------------- | | JOB\_TYPE\_UNSPECIFIED | 0 | **Deprecated.** | | JOB\_TYPE\_RULE\_EVALUATION | 1 | | | JOB\_TYPE\_DATA\_IMPORT | 2 | | | JOB\_TYPE\_DATA\_EXPORT | 3 | | # me Source: https://docs.siftstack.com/api/reference/protocol-buffers/me sift/me/v2/me.proto ## Services *RPC methods exposed by this API.* ### MeService | Method | Request | Response | Description | | :----- | :---------------------------- | :------------------------------ | :---------- | | GetMe | [GetMeRequest](#getmerequest) | [GetMeResponse](#getmeresponse) | | ## Messages *Data models used across requests/responses.* ### GetMeRequest *This message has no fields.* ### GetMeResponse | Field | Type | Label | Description | | :----------------------------------------- | :-------------------------------------------------------------------- | :------- | :-------------- | | user\_id | string | | | | user\_email | string | | | | organizations | [sift.common.type.v1.Organization](#sift-common-type-v1-organization) | repeated | | | is\_admin | bool | | | | permissions | [Permissions](#permissions) | | | | created\_date | google.protobuf.Timestamp | | | | hash\_based\_message\_authentication\_code | string | | **Deprecated.** | ### PermissionResources | Field | Type | Label | Description | | :-------------------- | :-------------------------------------------------------------------------------------------- | :------- | :---------- | | permission\_resources | [PermissionResources.PermissionResourcesEntry](#permissionresources-permissionresourcesentry) | repeated | | ### PermissionResources.PermissionResourcesEntry | Field | Type | Label | Description | | :---- | :---------------------- | :---- | :---------- | | key | string | | | | value | [Resources](#resources) | | | ### Permissions | Field | Type | Label | Description | | :---------------------------------- | :---------------------------------------------------------------------------------------------------- | :------- | :---------- | | organization\_permission\_resources | [Permissions.OrganizationPermissionResourcesEntry](#permissions-organizationpermissionresourcesentry) | repeated | | ### Permissions.OrganizationPermissionResourcesEntry | Field | Type | Label | Description | | :---- | :------------------------------------------ | :---- | :---------- | | key | string | | | | value | [PermissionResources](#permissionresources) | | | ### Resources | Field | Type | Label | Description | | :---------- | :----- | :------- | :---------- | | asset\_ids | string | repeated | | | all\_assets | bool | | | ## Enums *Allowed constant values used in message fields.* # metadata Source: https://docs.siftstack.com/api/reference/protocol-buffers/metadata sift/metadata/v1/metadata.proto ## Services *RPC methods exposed by this API.* ### MetadataService | Method | Request | Response | Description | | :---------------------- | :---------------------------------------------------------------- | :------------------------------------------------------------------ | :------------------------- | | CreateMetadataKey | [CreateMetadataKeyRequest](#createmetadatakeyrequest) | [CreateMetadataKeyResponse](#createmetadatakeyresponse) | Create a metadata key. | | CreateMetadataValue | [CreateMetadataValueRequest](#createmetadatavaluerequest) | [CreateMetadataValueResponse](#createmetadatavalueresponse) | Create a metadata value. | | ListMetadataKeys | [ListMetadataKeysRequest](#listmetadatakeysrequest) | [ListMetadataKeysResponse](#listmetadatakeysresponse) | List metadata keys. | | ListMetadataValues | [ListMetadataValuesRequest](#listmetadatavaluesrequest) | [ListMetadataValuesResponse](#listmetadatavaluesresponse) | List metadata values. | | ArchiveMetadataKeys | [ArchiveMetadataKeysRequest](#archivemetadatakeysrequest) | [ArchiveMetadataKeysResponse](#archivemetadatakeysresponse) | Archive metadata keys. | | ArchiveMetadataValues | [ArchiveMetadataValuesRequest](#archivemetadatavaluesrequest) | [ArchiveMetadataValuesResponse](#archivemetadatavaluesresponse) | Archive metadata values. | | UnarchiveMetadataKeys | [UnarchiveMetadataKeysRequest](#unarchivemetadatakeysrequest) | [UnarchiveMetadataKeysResponse](#unarchivemetadatakeysresponse) | Unarchive metadata keys. | | UnarchiveMetadataValues | [UnarchiveMetadataValuesRequest](#unarchivemetadatavaluesrequest) | [UnarchiveMetadataValuesResponse](#unarchivemetadatavaluesresponse) | Unarchive metadata values. | | DeleteMetadataKeys | [DeleteMetadataKeysRequest](#deletemetadatakeysrequest) | [DeleteMetadataKeysResponse](#deletemetadatakeysresponse) | Delete metadata keys. | | DeleteMetadataValues | [DeleteMetadataValuesRequest](#deletemetadatavaluesrequest) | [DeleteMetadataValuesResponse](#deletemetadatavaluesresponse) | Delete metadata values. | | ListMetadataUsage | [ListMetadataUsageRequest](#listmetadatausagerequest) | [ListMetadataUsageResponse](#listmetadatausageresponse) | List metadata key usage. | ## Messages *Data models used across requests/responses.* ### ArchiveMetadataKeysRequest | Field | Type | Label | Description | | :------------- | :-------------------------- | :------- | :---------- | | metadata\_keys | [MetadataKey](#metadatakey) | repeated | | ### ArchiveMetadataKeysResponse *This message has no fields.* ### ArchiveMetadataValuesRequest | Field | Type | Label | Description | | :--------------- | :------------------------------ | :------- | :---------- | | metadata\_values | [MetadataValue](#metadatavalue) | repeated | | ### ArchiveMetadataValuesResponse *This message has no fields.* ### CreateMetadataKeyRequest The request of a call to `MetadataService_CreateMetadataKey` to create a metadata key. | Field | Type | Label | Description | | :------------ | :-------------------------- | :---- | :---------- | | metadata\_key | [MetadataKey](#metadatakey) | | | ### CreateMetadataKeyResponse The response of a call to `MetadataService_CreateMetadataKey` to create a metadata key. | Field | Type | Label | Description | | :------------ | :-------------------------- | :---- | :---------- | | metadata\_key | [MetadataKey](#metadatakey) | | | ### CreateMetadataValueRequest The request of a call to `MetadataService_CreateMetadataValue` to create a metadata value. | Field | Type | Label | Description | | :-------------- | :------------------------------ | :---- | :---------- | | metadata\_value | [MetadataValue](#metadatavalue) | | | ### CreateMetadataValueResponse The response of a call to `MetadataService_CreateMetadataValue` to create a metadata value. | Field | Type | Label | Description | | :-------------- | :------------------------------ | :---- | :---------- | | metadata\_value | [MetadataValue](#metadatavalue) | | | ### DeleteMetadataKeysRequest | Field | Type | Label | Description | | :------------- | :-------------------------- | :------- | :---------- | | metadata\_keys | [MetadataKey](#metadatakey) | repeated | | ### DeleteMetadataKeysResponse *This message has no fields.* ### DeleteMetadataValuesRequest | Field | Type | Label | Description | | :--------------- | :------------------------------ | :------- | :---------- | | metadata\_values | [MetadataValue](#metadatavalue) | repeated | | ### DeleteMetadataValuesResponse *This message has no fields.* ### ListMetadataKeysRequest The request for a call to `MetadataService_ListMetadataKeys` to retrieve metadata keys. | Field | Type | Label | Description | | :---------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of metadata keys to return. The service may return fewer than this value. If unspecified, at most 50 metadata keys will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListMetadataKeys` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListMetadataKeys` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are: `name`, `archived_date`, and `is_archived`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). For more information about the fields used for filtering, please refer to this definition. Optional. | | order\_by | string | | How to order the retrieved metadata keys. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date` and `name`. If left empty, items are ordered by `created_date` in ascending order (oldest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | ### ListMetadataKeysResponse The response of a call to `MetadataService_ListMetadataKeysResponse`. | Field | Type | Label | Description | | :---------------- | :-------------------------- | :------- | :---------- | | metadata\_keys | [MetadataKey](#metadatakey) | repeated | | | next\_page\_token | string | | | ### ListMetadataUsageRequest | Field | Type | Label | Description | | :---------- | :----- | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of metadata key usages to return. The service may return fewer than this value. If unspecified, at most 50 metadata key usages will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListMetadataUsage` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListMetadataUsage` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are: `entity_name`, `entity_type`, `key_name`,`value_string`, `value_number`, and `value_boolean`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). For more information about the fields used for filtering, please refer to this definition. Optional. | | order\_by | string | | How to order the retrieved metadata key usages. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date`, `entity_id` and `entity_type`. If left empty, items are ordered by `created_date` in ascending order (oldest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc" | ### ListMetadataUsageResponse | Field | Type | Label | Description | | :---------------- | :------------------------------ | :------- | :---------- | | metadata\_usages | [MetadataUsage](#metadatausage) | repeated | | | next\_page\_token | string | | | ### ListMetadataValuesRequest | Field | Type | Label | Description | | :------------------ | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | page\_size | uint32 | | The maximum number of metadata values to return. The service may return fewer than this value. If unspecified, at most 50 metadata values will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListMetadataValues` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListMetadataValues` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are: `value_string`, `value_number`, `value_boolean`, `archived_date`, and `is_archived`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). For more information about the fields used for filtering, please refer to this definition. Optional. | | order\_by | string | | How to order the retrieved metadata keys. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date` and `name`. If left empty, items are ordered by `created_date` in ascending order (oldest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | | metadata\_key\_name | string | | The name of the metadata key to list values for. | ### ListMetadataValuesResponse | Field | Type | Label | Description | | :---------------- | :------------------------------ | :------- | :---------- | | metadata\_values | [MetadataValue](#metadatavalue) | repeated | | | next\_page\_token | string | | | ### MetadataKey | Field | Type | Label | Description | | :------------- | :---------------------------------- | :---- | :----------------------------------------------------------------------------------------- | | name | string | | | | type | [MetadataKeyType](#metadatakeytype) | | | | archived\_date | google.protobuf.Timestamp | | | | is\_archived | bool | | Whether the metadata key is archived. This is inferred from whether archived\_date is set. | The filter field type this key maps to, so a client can build a CEL filter against it (`metadata[""]`) and resolve its operators and functions from FilterGrammarService. Derived from `type`. | ### MetadataRelationValue | Field | Type | Label | Description | | :------------- | :----- | :---- | :---------- | | resource\_type | string | | | | resource\_id | string | | | ### MetadataUsage | Field | Type | Label | Description | | :----------- | :------------------------------ | :---- | :--------------------------------------------------------------- | | entity\_id | string | | The ID of the entity. For example assetId, runId, reportId, etc. | | entity\_type | string | | The type of the entity. For example asset, run, report, etc. | | value | [MetadataValue](#metadatavalue) | | The value of the metadata key on this entity. | ### MetadataValue | Field | Type | Label | Description | | :--------------------------- | :---------------------------------------------- | :---- | :------------------------------------------------------------------------------------------- | | key | [MetadataKey](#metadatakey) | | | | oneof value. string\_value | string | | | | oneof value. number\_value | double | | | | oneof value. boolean\_value | bool | | | | oneof value. relation\_value | [MetadataRelationValue](#metadatarelationvalue) | | | | archived\_date | google.protobuf.Timestamp | | | | is\_archived | bool | | Whether the metadata value is archived. This is inferred from whether archived\_date is set. | ### UnarchiveMetadataKeysRequest | Field | Type | Label | Description | | :---------------- | :-------------------------- | :------- | :---------- | | metadata\_keys | [MetadataKey](#metadatakey) | repeated | | | unarchive\_values | bool | | | ### UnarchiveMetadataKeysResponse *This message has no fields.* ### UnarchiveMetadataValuesRequest | Field | Type | Label | Description | | :--------------- | :------------------------------ | :------- | :---------- | | metadata\_values | [MetadataValue](#metadatavalue) | repeated | | ### UnarchiveMetadataValuesResponse *This message has no fields.* ## Enums *Allowed constant values used in message fields.* ### MetadataKeyType Metadata key type. | Name | Number | Description | | :------------------------------- | :----- | :---------------------------------------------------------------------- | | METADATA\_KEY\_TYPE\_UNSPECIFIED | 0 | | | METADATA\_KEY\_TYPE\_STRING | 1 | string | | METADATA\_KEY\_TYPE\_NUMBER | 2 | number | | METADATA\_KEY\_TYPE\_BOOLEAN | 3 | boolean | | METADATA\_KEY\_TYPE\_RELATION | 4 | relation — references another resource by UUID (e.g. folder membership) | # notifications Source: https://docs.siftstack.com/api/reference/protocol-buffers/notifications sift/notifications/v1/notifications.proto ## Services *RPC methods exposed by this API.* ### NotificationService | Method | Request | Response | Description | | :----------------------- | :------------------------------------------------------------------ | :-------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------- | | ListNotifications | [ListNotificationsRequest](#listnotificationsrequest) | [ListNotificationsResponse](#listnotificationsresponse) | Retrieves notifications using an optional filter. | | BatchUpdateNotifications | [BatchUpdateNotificationsRequest](#batchupdatenotificationsrequest) | [BatchUpdateNotificationsResponse](#batchupdatenotificationsresponse) | Batch updates a list of notifications using the list of fields specified in their respective `update_mask`s. | ## Messages *Data models used across requests/responses.* ### BatchUpdateNotificationsRequest The request for a call to `NotificationService_BatchUpdateNotifications` to update notifications. A maximum of 1000 notifications can be modified in a batch. | Field | Type | Label | Description | | :------- | :------------------------------------------------------ | :------- | :---------- | | requests | [UpdateNotificationRequest](#updatenotificationrequest) | repeated | | ### BatchUpdateNotificationsResponse The response of a call to `NotificationService_BatchUpdateNotifications` containing the updated notifications. | Field | Type | Label | Description | | :------------ | :---------------------------- | :------- | :------------------------- | | notifications | [Notification](#notification) | repeated | The updated notifications. | ### ListNotificationsRequest The request for a call to `NotificationService_ListNotifications` to retrieve notifications. | Field | Type | Label | Description | | :---------- | :----- | :---- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of notifications to return. The service may return fewer than this value. If unspecified, at most 50 notifications will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. | | page\_token | string | | A page token, received from a previous `ListNotifications` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListNotifications` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `notification_id`, `created_by_user_id`, `recipient_user_id`, `created_date`, `notification_type`, and `is_read`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | ### ListNotificationsResponse The response of a call to `NotificationService_ListNotifications`. | Field | Type | Label | Description | | :---------------- | :---------------------------- | :------- | :---------- | | notifications | [Notification](#notification) | repeated | | | next\_page\_token | string | | | ### Notification | Field | Type | Label | Description | | :--------------------- | :------------------------------------ | :---- | :---------- | | notification\_id | string | | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | organization\_id | string | | | | recipient\_user\_id | string | | | | is\_read | bool | | | | full\_link | string | | | | notification\_type | [NotificationKind](#notificationkind) | | | | contents | string | | | | entity\_id | string | | | ### UpdateNotificationRequest | Field | Type | Label | Description | | :----------- | :------------------------------------------------------ | :---- | :------------------------------------------------------------------------------------------------------------------------------------------ | | notification | [Notification](#notification) | | The notification to update. The notification's `notification_id` field is used to identify the notification to update and must be provided. | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The list of fields to be updated. Currently, the only field that can be updated is `is_read`. | ## Enums *Allowed constant values used in message fields.* ### NotificationKind | Name | Number | Description | | :----------------------------------------------------- | :----- | :---------- | | NOTIFICATION\_KIND\_UNSPECIFIED | 0 | | | NOTIFICATION\_KIND\_TEXT | 1 | | | NOTIFICATION\_KIND\_ANNOTATION\_ASSIGNED | 2 | | | NOTIFICATION\_KIND\_MENTIONED\_IN\_ANNOTATION\_COMMENT | 3 | | | NOTIFICATION\_KIND\_CONDITION\_TRIGGERED | 4 | | | NOTIFICATION\_KIND\_ANNOTATION\_STATE\_CHANGED | 5 | | | NOTIFICATION\_KIND\_REPORT\_READY | 6 | | | NOTIFICATION\_KIND\_DATA\_EXPORT\_READY | 7 | | | NOTIFICATION\_KIND\_MENTIONED\_IN\_COMMENT | 8 | | | NOTIFICATION\_KIND\_AUTOMATION\_TRIGGER\_DISPATCHED | 9 | | # organization Source: https://docs.siftstack.com/api/reference/protocol-buffers/organization sift/common/type/v1/organization.proto ## Services *RPC methods exposed by this API.* ## Messages *Data models used across requests/responses.* ### Organization | Field | Type | Label | Description | | :----------------- | :----- | :------- | :---------- | | organization\_id | string | | | | organization\_name | string | | | | is\_abac\_enabled | bool | optional | | ## Enums *Allowed constant values used in message fields.* # panel_configuration Source: https://docs.siftstack.com/api/reference/protocol-buffers/panel_configuration sift/panel_configurations/v1/panel_configuration.proto ## Services *RPC methods exposed by this API.* ### PanelConfigurationService | Method | Request | Response | Description | | :----------------------- | :------------------------------------------------------------------ | :-------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------- | | GetPanelConfiguration | [GetPanelConfigurationRequest](#getpanelconfigurationrequest) | [GetPanelConfigurationResponse](#getpanelconfigurationresponse) | Retrieves a panel configuration. | | ListPanelConfigurations | [ListPanelConfigurationsRequest](#listpanelconfigurationsrequest) | [ListPanelConfigurationsResponse](#listpanelconfigurationsresponse) | Retrieves panel configurations using an optional filter. | | CreatePanelConfiguration | [CreatePanelConfigurationRequest](#createpanelconfigurationrequest) | [CreatePanelConfigurationResponse](#createpanelconfigurationresponse) | Creates a panel configuration. | | UpdatePanelConfiguration | [UpdatePanelConfigurationRequest](#updatepanelconfigurationrequest) | [UpdatePanelConfigurationResponse](#updatepanelconfigurationresponse) | Updates an existing panel configuration using using the list of fields specified in `update_mask`. | ## Messages *Data models used across requests/responses.* ### ChannelConfigurations | Field | Type | Label | Description | | :------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------- | :------- | :--------------------------------------------------------------------- | | name | string | | | | type | [PlottedChannelType](#plottedchanneltype) | | | | color | string | | | | channel\_settings | google.protobuf.Struct | | | | bit\_field\_index | int32 | optional | bitfield | | bit\_field\_element | [sift.common.type.v1.ChannelBitFieldElement](#sift-common-type-v1-channelbitfieldelement) | optional | | | expression | string | optional | temporary calculated channel | | expression\_channel\_references | [sift.calculated\_channels.v2.CalculatedChannelAbstractChannelReference](#sift-calculated_channels-v2-calculatedchannelabstractchannelreference) | repeated | | | data\_type | [sift.common.type.v1.ChannelDataType](#sift-common-type-v1-channeldatatype) | optional | | | calculated\_channel\_id | string | optional | published calculated channel reference; preferred over name for lookup | ### CreatePanelConfigurationRequest | Field | Type | Label | Description | | :---------------------- | :---------------------------------------------------------------- | :------- | :---------- | | name | string | | | | channel\_configurations | [ChannelConfigurations](#channelconfigurations) | repeated | | | chart\_settings | google.protobuf.Struct | optional | | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | | ### CreatePanelConfigurationResponse | Field | Type | Label | Description | | :------------------- | :---------------------------------------- | :---- | :---------- | | panel\_configuration | [PanelConfiguration](#panelconfiguration) | | | ### GetPanelConfigurationRequest | Field | Type | Label | Description | | :----------------------- | :----- | :---- | :---------- | | panel\_configuration\_id | string | | | ### GetPanelConfigurationResponse | Field | Type | Label | Description | | :------------------- | :---------------------------------------- | :---- | :---------- | | panel\_configuration | [PanelConfiguration](#panelconfiguration) | | | ### ListPanelConfigurationsRequest | Field | Type | Label | Description | | :---------- | :----- | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of panel configurations to return. The service may return fewer than this value. If unspecified, at most 50 panel configurations will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. | | page\_token | string | | A page token, received from a previous `ListPanelConfigurations` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListPanelConfigurations` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string Available fields to filter by are 'name', 'created\_date', 'modified\_date', 'is\_archived', and `metadata`. Metadata can be used in filters by using `metadata.{metadata_key_name}` as the field name. Folder membership is filterable via the `folders` and `activeFolders` fields. Both contain the ids of the folders the panel configuration belongs to; `activeFolders` excludes archived folders. Use `"" in folders` to return panel configurations in the given folder, and `size(activeFolders) == 0` to return uncategorized panel configurations (panel configurations whose only memberships are in archived folders count as uncategorized). For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved panel configurations. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `name`. If left empty, items are ordered by `name` in ascending order (alphabetical). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "name" | | run\_ids | string | repeated | | | asset\_ids | string | repeated | | ### ListPanelConfigurationsResponse | Field | Type | Label | Description | | :-------------------- | :---------------------------------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------- | | panel\_configurations | [PanelConfiguration](#panelconfiguration) | repeated | | | next\_page\_token | string | | A token, which can be sent as `page_token` to retrieve the next page. If this field is omitted, there are no subsequent pages. | ### PanelConfiguration | Field | Type | Label | Description | | :----------------------- | :---------------------------------------------------------------- | :------- | :------------------------------------------------------ | | panel\_configuration\_id | string | | | | version\_id | string | | | | version | uint32 | | | | change\_message | string | | | | name | string | | | | channel\_configurations | [ChannelConfigurations](#channelconfigurations) | repeated | | | chart\_settings | google.protobuf.Struct | optional | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | archived\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | is\_archived | bool | | | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | | | folder\_ids | string | repeated | Ids of the folders this panel configuration belongs to. | ### UpdatePanelConfigurationRequest The request for a call to `PanelConfigurationService_UpdatePanelConfiguration` to update a panel configuration. Updating a panel configuration creates a new version of the panel configuration, leaving the previous untouched. If no update is deemed necessary, then the the current version is returned. Use `is_archived` to archive/unarchive a panel configuration. | Field | Type | Label | Description | | :------------------- | :------------------------------------------------------ | :---- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | | panel\_configuration | [PanelConfiguration](#panelconfiguration) | | The panel configuration to update. | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The list of fields to be updated. The fields available to be updated are `name`, `channel_configurations`, `chart_settings`, `is_archived`, and `metadata`. | ### UpdatePanelConfigurationResponse | Field | Type | Label | Description | | :------------------- | :---------------------------------------- | :---- | :---------- | | panel\_configuration | [PanelConfiguration](#panelconfiguration) | | | ## Enums *Allowed constant values used in message fields.* ### PlottedChannelType | Name | Number | Description | | :------------------------------------------ | :----- | :-------------- | | PLOTTED\_CHANNEL\_TYPE\_UNSPECIFIED | 0 | **Deprecated.** | | PLOTTED\_CHANNEL\_TYPE\_REGULAR | 1 | | | PLOTTED\_CHANNEL\_TYPE\_CALCULATED\_CHANNEL | 2 | | | PLOTTED\_CHANNEL\_TYPE\_BIT\_FIELD\_ELEMENT | 3 | | | PLOTTED\_CHANNEL\_TYPE\_ENUM | 4 | | # ping Source: https://docs.siftstack.com/api/reference/protocol-buffers/ping sift/ping/v1/ping.proto ## Services *RPC methods exposed by this API.* ### PingService | Method | Request | Response | Description | | :----- | :-------------------------- | :---------------------------- | :---------- | | Ping | [PingRequest](#pingrequest) | [PingResponse](#pingresponse) | | ## Messages *Data models used across requests/responses.* ### PingRequest *This message has no fields.* ### PingResponse | Field | Type | Label | Description | | :------- | :----- | :---- | :---------- | | response | string | | | ## Enums *Allowed constant values used in message fields.* # policies Source: https://docs.siftstack.com/api/reference/protocol-buffers/policies sift/policies/v1/policies.proto ## Services *RPC methods exposed by this API.* ### PolicyService | Method | Request | Response | Description | | :-------------- | :------------------------------------------------ | :-------------------------------------------------- | :------------------------------------------ | | GetPolicy | [GetPolicyRequest](#getpolicyrequest) | [GetPolicyResponse](#getpolicyresponse) | Retrieve a policy | | ListPolicies | [ListPoliciesRequest](#listpoliciesrequest) | [ListPoliciesResponse](#listpoliciesresponse) | Retrieve policies using an optional filter. | | CreatePolicy | [CreatePolicyRequest](#createpolicyrequest) | [CreatePolicyResponse](#createpolicyresponse) | Create a policy | | UpdatePolicy | [UpdatePolicyRequest](#updatepolicyrequest) | [UpdatePolicyResponse](#updatepolicyresponse) | Update a policy | | ValidatePolicy | [ValidatePolicyRequest](#validatepolicyrequest) | [ValidatePolicyResponse](#validatepolicyresponse) | Validate a Cedar policy configuration | | ArchivePolicy | [ArchivePolicyRequest](#archivepolicyrequest) | [ArchivePolicyResponse](#archivepolicyresponse) | Archive a policy | | UnarchivePolicy | [UnarchivePolicyRequest](#unarchivepolicyrequest) | [UnarchivePolicyResponse](#unarchivepolicyresponse) | Unarchive a policy | ## Messages *Data models used across requests/responses.* ### ArchivePolicyRequest The request for a call to `PolicyService_ArchivePolicy` to archive a policy. | Field | Type | Label | Description | | :--------- | :----- | :---- | :---------- | | policy\_id | string | | | ### ArchivePolicyResponse The response of a call to `PolicyService_ArchivePolicy`. | Field | Type | Label | Description | | :----- | :---------------- | :---- | :---------- | | policy | [Policy](#policy) | | | ### CreatePolicyRequest The request for a call to `PolicyService_CreatePolicy` to create a new policy. | Field | Type | Label | Description | | :------------- | :------------------------------------------ | :------- | :------------------------------ | | name | string | | | | description | string | optional | | | configuration | [PolicyConfiguration](#policyconfiguration) | | Policy rules/configuration | | version\_notes | string | optional | Optional notes for this version | ### CreatePolicyResponse The response of a call to `PolicyService_CreatePolicy`. | Field | Type | Label | Description | | :----- | :---------------- | :---- | :---------- | | policy | [Policy](#policy) | | | ### GetPolicyRequest The request for a call to `PolicyService_GetPolicy`. | Field | Type | Label | Description | | :--------- | :----- | :---- | :---------- | | policy\_id | string | | | ### GetPolicyResponse The response of a call to `PolicyService_GetPolicy`. | Field | Type | Label | Description | | :----- | :---------------- | :---- | :---------- | | policy | [Policy](#policy) | | | ### ListPoliciesRequest The request for a call to `PolicyService_ListPolicies` to retrieve policies. | Field | Type | Label | Description | | :---------------- | :----- | :---- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of policies to return. The service may return fewer than this value. If unspecified, at most 50 policies will be returned. The maximum value is 100; values above 100 will be coerced to 100. Optional. | | page\_token | string | | A page token, received from a previous `ListPolicies` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListPolicies` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `policy_id`, `organization_id`, `name`, `description`, `created_by_user_id`, `modified_by_user_id`, `created_date`, and `modified_date`. Archive state is controlled via the `include_archived` field below, not via filter. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved policies. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date`, `modified_date`, and `name`. If left empty, items are ordered by `created_date` in descending order (newest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | | include\_archived | bool | | Whether to include archived policies in the response. If false or unset, archived policies are excluded. | ### ListPoliciesResponse The result of a call to `PolicyService_ListPolicies`. | Field | Type | Label | Description | | :---------------- | :---------------- | :------- | :---------- | | policies | [Policy](#policy) | repeated | | | next\_page\_token | string | | | ### Policy | Field | Type | Label | Description | | :------------------------- | :------------------------------------------ | :------- | :--------------------------------------------- | | policy\_id | string | | | | name | string | | | | description | string | optional | | | organization\_id | string | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | configuration | [PolicyConfiguration](#policyconfiguration) | | Policy rules/configuration | | policy\_version\_id | string | | Reference to the current policy version ID | | archived\_date | google.protobuf.Timestamp | | The date the policy was archived. | | is\_archived | bool | | | | version | int32 | optional | Optional version number for this policy | | version\_notes | string | optional | Optional notes for this version | | generated\_change\_message | string | optional | Auto-generated change message for this version | ### PolicyConfiguration PolicyConfiguration represents the configuration and rules for a policy. Expects a string containing a policy in the Cedar format [https://docs.cedarpolicy.com/policies/syntax-policy.html](https://docs.cedarpolicy.com/policies/syntax-policy.html) | Field | Type | Label | Description | | :------------ | :----- | :---- | :---------- | | cedar\_policy | string | | | ### UnarchivePolicyRequest The request for a call to `PolicyService_UnarchivePolicy` to unarchive a previously-archived policy. | Field | Type | Label | Description | | :--------- | :----- | :---- | :---------- | | policy\_id | string | | | ### UnarchivePolicyResponse The response of a call to `PolicyService_UnarchivePolicy`. | Field | Type | Label | Description | | :----- | :---------------- | :---- | :---------- | | policy | [Policy](#policy) | | | ### UpdatePolicyRequest The request for a call to `PolicyService_UpdatePolicy` to update a policy. | Field | Type | Label | Description | | :------------- | :------------------------------------------------------ | :------- | :---------------------------------------------------------------------------------------------------------------------------------- | | policy | [Policy](#policy) | | | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The list of fields to be updated. The fields available to be updated are `name`, `description`, `configuration`, and `is_archived`. | | version\_notes | string | optional | Optional notes for the new policy version when configuration changes | ### UpdatePolicyResponse The response of a call to `PolicyService_UpdatePolicy`. | Field | Type | Label | Description | | :----- | :---------------- | :---- | :---------- | | policy | [Policy](#policy) | | | ### ValidatePolicyRequest The request for a call to `PolicyService_ValidatePolicy`. | Field | Type | Label | Description | | :------------ | :----- | :---- | :---------- | | cedar\_policy | string | | | ### ValidatePolicyResponse The response of a call to `PolicyService_ValidatePolicy`. | Field | Type | Label | Description | | :--------------- | :----- | :------- | :---------- | | valid | bool | | | | failure\_message | string | optional | | ## Enums *Allowed constant values used in message fields.* # principal_attributes Source: https://docs.siftstack.com/api/reference/protocol-buffers/principal_attributes sift/principal_attributes/v1/principal_attributes.proto ## Services *RPC methods exposed by this API.* ### PrincipalAttributeService | Method | Request | Response | Description | | :----------------------------------------- | :------------------------------------------------------------------------------------------------------ | :-------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | CreatePrincipalAttributeKey | [CreatePrincipalAttributeKeyRequest](#createprincipalattributekeyrequest) | [CreatePrincipalAttributeKeyResponse](#createprincipalattributekeyresponse) | Creates a principal attribute key. | | GetPrincipalAttributeKey | [GetPrincipalAttributeKeyRequest](#getprincipalattributekeyrequest) | [GetPrincipalAttributeKeyResponse](#getprincipalattributekeyresponse) | Retrieves a principal attribute key. | | ListPrincipalAttributeKeys | [ListPrincipalAttributeKeysRequest](#listprincipalattributekeysrequest) | [ListPrincipalAttributeKeysResponse](#listprincipalattributekeysresponse) | Lists principal attribute keys, respecting the provided filter. | | UpdatePrincipalAttributeKey | [UpdatePrincipalAttributeKeyRequest](#updateprincipalattributekeyrequest) | [UpdatePrincipalAttributeKeyResponse](#updateprincipalattributekeyresponse) | Updates an existing principal attribute key. | | CheckPrincipalAttributeKeyArchiveImpact | [CheckPrincipalAttributeKeyArchiveImpactRequest](#checkprincipalattributekeyarchiveimpactrequest) | [CheckPrincipalAttributeKeyArchiveImpactResponse](#checkprincipalattributekeyarchiveimpactresponse) | | | ArchivePrincipalAttributeKeys | [ArchivePrincipalAttributeKeysRequest](#archiveprincipalattributekeysrequest) | [ArchivePrincipalAttributeKeysResponse](#archiveprincipalattributekeysresponse) | Batch archives principal attribute keys AND all their associated principal attribute values. | | UnarchivePrincipalAttributeKeys | [UnarchivePrincipalAttributeKeysRequest](#unarchiveprincipalattributekeysrequest) | [UnarchivePrincipalAttributeKeysResponse](#unarchiveprincipalattributekeysresponse) | Batch unarchives principal attribute keys. | | BatchCreatePrincipalAttributeValue | [BatchCreatePrincipalAttributeValueRequest](#batchcreateprincipalattributevaluerequest) | [BatchCreatePrincipalAttributeValueResponse](#batchcreateprincipalattributevalueresponse) | Creates a principal attribute value for multiple principals in a single operation. | | GetPrincipalAttributeValue | [GetPrincipalAttributeValueRequest](#getprincipalattributevaluerequest) | [GetPrincipalAttributeValueResponse](#getprincipalattributevalueresponse) | Retrieves a principal attribute value. | | ListPrincipalAttributeKeyValues | [ListPrincipalAttributeKeyValuesRequest](#listprincipalattributekeyvaluesrequest) | [ListPrincipalAttributeKeyValuesResponse](#listprincipalattributekeyvaluesresponse) | Lists principal attribute values for a given principal attribute key, respecting the provided filter. | | ListPrincipalAttributeValues | [ListPrincipalAttributeValuesRequest](#listprincipalattributevaluesrequest) | [ListPrincipalAttributeValuesResponse](#listprincipalattributevaluesresponse) | Lists principal attribute values, respecting the provided filter. | | ArchivePrincipalAttributeValues | [ArchivePrincipalAttributeValuesRequest](#archiveprincipalattributevaluesrequest) | [ArchivePrincipalAttributeValuesResponse](#archiveprincipalattributevaluesresponse) | Batch archives principal attribute values. | | UnarchivePrincipalAttributeValues | [UnarchivePrincipalAttributeValuesRequest](#unarchiveprincipalattributevaluesrequest) | [UnarchivePrincipalAttributeValuesResponse](#unarchiveprincipalattributevaluesresponse) | Batch unarchives principal attribute values. | | CreatePrincipalAttributeEnumValue | [CreatePrincipalAttributeEnumValueRequest](#createprincipalattributeenumvaluerequest) | [CreatePrincipalAttributeEnumValueResponse](#createprincipalattributeenumvalueresponse) | Creates a principal attribute enum value. | | GetPrincipalAttributeEnumValue | [GetPrincipalAttributeEnumValueRequest](#getprincipalattributeenumvaluerequest) | [GetPrincipalAttributeEnumValueResponse](#getprincipalattributeenumvalueresponse) | Retrieves a principal attribute enum value. | | ListPrincipalAttributeEnumValues | [ListPrincipalAttributeEnumValuesRequest](#listprincipalattributeenumvaluesrequest) | [ListPrincipalAttributeEnumValuesResponse](#listprincipalattributeenumvaluesresponse) | Lists principal attribute enum values for a given principal attribute key. | | UpdatePrincipalAttributeEnumValue | [UpdatePrincipalAttributeEnumValueRequest](#updateprincipalattributeenumvaluerequest) | [UpdatePrincipalAttributeEnumValueResponse](#updateprincipalattributeenumvalueresponse) | Updates an existing principal attribute enum value. | | ArchivePrincipalAttributeEnumValue | [ArchivePrincipalAttributeEnumValueRequest](#archiveprincipalattributeenumvaluerequest) | [ArchivePrincipalAttributeEnumValueResponse](#archiveprincipalattributeenumvalueresponse) | Archives a principal attribute enum value and migrates all principal attribute values with that enum value to a replacement enum value. | | UnarchivePrincipalAttributeEnumValue | [UnarchivePrincipalAttributeEnumValueRequest](#unarchiveprincipalattributeenumvaluerequest) | [UnarchivePrincipalAttributeEnumValueResponse](#unarchiveprincipalattributeenumvalueresponse) | Unarchives a principal attribute enum value BUT DOES NOT migrate principal attribute values with a replacement value back to the original value. | | BatchArchivePrincipalAttributeEnumValues | [BatchArchivePrincipalAttributeEnumValuesRequest](#batcharchiveprincipalattributeenumvaluesrequest) | [BatchArchivePrincipalAttributeEnumValuesResponse](#batcharchiveprincipalattributeenumvaluesresponse) | Archives multiple principal attribute enum values and migrates all principal attribute values with those enum values to their respective replacement enum values. | | BatchUnarchivePrincipalAttributeEnumValues | [BatchUnarchivePrincipalAttributeEnumValuesRequest](#batchunarchiveprincipalattributeenumvaluesrequest) | [BatchUnarchivePrincipalAttributeEnumValuesResponse](#batchunarchiveprincipalattributeenumvaluesresponse) | Unarchives multiple principal attribute enum values BUT DOES NOT migrate principal attribute values with a replacement value back to the original value. | ## Messages *Data models used across requests/responses.* ### ArchivePrincipalAttributeEnumValueRequest | Field | Type | Label | Description | | :--------------------------- | :----- | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | archived\_enum\_value\_id | string | | | | replacement\_enum\_value\_id | string | | When the archived\_enum\_value\_id is archived all principal attribute values that reference it will be migrated to the replacement\_enum\_value\_id if provided. Otherwise, user-attributes that reference it will be archived as well. | ### ArchivePrincipalAttributeEnumValueResponse | Field | Type | Label | Description | | :------------------------------------- | :---- | :---- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | principal\_attribute\_values\_migrated | int32 | | Total number of principal attribute values migrated or archived by this operation. When a replacement enum value is provided, this represents values migrated to the new value. When no replacement is provided, this represents values that were archived. | ### ArchivePrincipalAttributeKeysRequest ArchivePrincipalAttributeKeysRequest is used to batch archive principal attribute keys by id. | Field | Type | Label | Description | | :----------------------------- | :----- | :------- | :---------- | | principal\_attribute\_key\_ids | string | repeated | | ### ArchivePrincipalAttributeKeysResponse *This message has no fields.* ### ArchivePrincipalAttributeValuesRequest ArchivePrincipalAttributeValuesRequest is used to batch archive principal attribute values by id. | Field | Type | Label | Description | | :------------------------------- | :------------------------------------------------------------------ | :------- | :---------- | | principal\_attribute\_value\_ids | string | repeated | | | principal\_type | [PrincipalAttributePrincipalType](#principalattributeprincipaltype) | | | ### ArchivePrincipalAttributeValuesResponse *This message has no fields.* ### BatchArchivePrincipalAttributeEnumValuesRequest | Field | Type | Label | Description | | :----------------- | :-------------------------------------------------------------------------------------------------------------------------------------- | :------- | :---------- | | archival\_requests | [BatchArchivePrincipalAttributeEnumValuesRequest.EnumValueArchival](#batcharchiveprincipalattributeenumvaluesrequest-enumvaluearchival) | repeated | | ### BatchArchivePrincipalAttributeEnumValuesRequest.EnumValueArchival | Field | Type | Label | Description | | :--------------------------- | :----- | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | archived\_enum\_value\_id | string | | The enum value ID to archive. | | replacement\_enum\_value\_id | string | | When the archived\_enum\_value\_id is archived all principal attribute values that reference it will be migrated to the replacement\_enum\_value\_id if provided. Otherwise, user-attributes that reference it will be archived as well. | ### BatchArchivePrincipalAttributeEnumValuesResponse | Field | Type | Label | Description | | :-------------------------------------------- | :---- | :---- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | total\_principal\_attribute\_values\_migrated | int32 | | Total number of principal attribute values migrated or archived across all enum value operations. This includes both values migrated to replacement values and values archived without replacement. | ### BatchCreatePrincipalAttributeValueRequest BatchCreatePrincipalAttributeValueRequest is used to batch create new principal attribute values. | Field | Type | Label | Description | | :-------------------------------------------------- | :---------------------------------------------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | principal\_attribute\_key\_id | string | | | | principal\_ids | string | repeated | | | principal\_type | [PrincipalAttributePrincipalType](#principalattributeprincipaltype) | | | | oneof value. principal\_attribute\_enum\_value\_id | string | | For ENUM type: exactly one enum value ID. | | oneof value. principal\_attribute\_enum\_value\_ids | [PrincipalAttributeEnumValueIdList](#principalattributeenumvalueidlist) | | For SET\_OF\_ENUM type: one or more enum value IDs representing the complete desired set. Omitted enum values that are currently active for each principal+key will be archived. | | oneof value. number\_value | int64 | | | | oneof value. boolean\_value | bool | | | ### BatchCreatePrincipalAttributeValueResponse BatchCreatePrincipalAttributeValueResponse returns the principal attribute values from a BatchCreatePrincipalAttributeValue call. | Field | Type | Label | Description | | :--------------------------- | :-------------------------------------------------- | :------- | :---------- | | principal\_attribute\_values | [PrincipalAttributeValue](#principalattributevalue) | repeated | | ### BatchUnarchivePrincipalAttributeEnumValuesRequest | Field | Type | Label | Description | | :------------------------------------- | :----- | :------- | :---------- | | principal\_attribute\_enum\_value\_ids | string | repeated | | ### BatchUnarchivePrincipalAttributeEnumValuesResponse *This message has no fields.* ### CheckPrincipalAttributeKeyArchiveImpactRequest | Field | Type | Label | Description | | :---------------------------- | :----- | :---- | :---------- | | principal\_attribute\_key\_id | string | | | ### CheckPrincipalAttributeKeyArchiveImpactResponse | Field | Type | Label | Description | | :------------------------------------------------------ | :---- | :---- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | active\_user\_principal\_attribute\_value\_count | int64 | | Non-archived user principal-attribute value rows for this key that will be archived with the key (same scope as ArchivePrincipalAttributeKeys; includes multiple rows per principal for SET\_OF\_ENUM). | | active\_user\_group\_principal\_attribute\_value\_count | int64 | | Non-archived user\_group\_attribute\_values rows for this key. They are not archived by ArchivePrincipalAttributeKeys, but stop contributing to principal.groupAttributes once the key is archived (evaluation joins active keys only). | ### CreatePrincipalAttributeEnumValueRequest Principal Attribute Enum Value RPC messages | Field | Type | Label | Description | | :---------------------------- | :----- | :---- | :---------- | | principal\_attribute\_key\_id | string | | | | display\_name | string | | | | description | string | | | ### CreatePrincipalAttributeEnumValueResponse | Field | Type | Label | Description | | :-------------------------------- | :---------------------------------------------------------- | :---- | :---------- | | principal\_attribute\_enum\_value | [PrincipalAttributeEnumValue](#principalattributeenumvalue) | | | ### CreatePrincipalAttributeKeyRequest CreatePrincipalAttributeKeyRequest is used to create a new principal attribute key. | Field | Type | Label | Description | | :-------------------- | :---------------------------------------------------------------------------------------------------------- | :------- | :-------------------------------------------------------------------------------------------- | | display\_name | string | | | | description | string | | | | type | [PrincipalAttributeValueType](#principalattributevaluetype) | | | | initial\_enum\_values | [CreatePrincipalAttributeKeyRequest.InitialEnumValue](#createprincipalattributekeyrequest-initialenumvalue) | repeated | Optional initial enum values to create alongside the key. Only applicable for ENUM type keys. | ### CreatePrincipalAttributeKeyRequest.InitialEnumValue Nested message for initial enum values in create requests. | Field | Type | Label | Description | | :------------ | :----- | :---- | :---------- | | display\_name | string | | | | description | string | | | ### CreatePrincipalAttributeKeyResponse CreatePrincipalAttributeKeyResponse returns the principal attribute key from a CreatePrincipalAttributeKey call. | Field | Type | Label | Description | | :------------------------ | :---------------------------------------------------------- | :------- | :------------------------------------------------------------------------------ | | principal\_attribute\_key | [PrincipalAttributeKey](#principalattributekey) | | | | enum\_values | [PrincipalAttributeEnumValue](#principalattributeenumvalue) | repeated | The enum values created alongside the key, if any were provided in the request. | ### GetPrincipalAttributeEnumValueRequest | Field | Type | Label | Description | | :------------------------------------ | :----- | :---- | :---------- | | principal\_attribute\_enum\_value\_id | string | | | ### GetPrincipalAttributeEnumValueResponse | Field | Type | Label | Description | | :-------------------------------- | :---------------------------------------------------------- | :---- | :---------- | | principal\_attribute\_enum\_value | [PrincipalAttributeEnumValue](#principalattributeenumvalue) | | | ### GetPrincipalAttributeKeyRequest GetPrincipalAttributeKeyRequest is used to retrieve a principal attribute key. | Field | Type | Label | Description | | :---------------------------- | :----- | :---- | :---------- | | principal\_attribute\_key\_id | string | | | ### GetPrincipalAttributeKeyResponse GetPrincipalAttributeKeyResponse returns a principal attribute key from a GetPrincipalAttributeKey call. | Field | Type | Label | Description | | :------------------------ | :---------------------------------------------- | :---- | :---------- | | principal\_attribute\_key | [PrincipalAttributeKey](#principalattributekey) | | | ### GetPrincipalAttributeValueRequest GetPrincipalAttributeValueRequest is used to retrieve a principal attribute value. | Field | Type | Label | Description | | :------------------------------ | :------------------------------------------------------------------ | :---- | :---------- | | principal\_attribute\_value\_id | string | | | | principal\_type | [PrincipalAttributePrincipalType](#principalattributeprincipaltype) | | | ### GetPrincipalAttributeValueResponse GetPrincipalAttributeValueResponse returns a principal attribute value from a GetPrincipalAttributeValue call. | Field | Type | Label | Description | | :-------------------------- | :-------------------------------------------------- | :---- | :---------- | | principal\_attribute\_value | [PrincipalAttributeValue](#principalattributevalue) | | | ### ListPrincipalAttributeEnumValuesRequest | Field | Type | Label | Description | | :---------------------------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | principal\_attribute\_key\_id | string | | | | page\_size | uint32 | | The maximum number of enum values to return. The service may return fewer than this value. If unspecified, at most 50 enum values will be returned. The maximum value is 100; values above 100 will be coerced to 100. | | page\_token | string | | A page token, received from a previous `ListPrincipalAttributeEnumValues` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListPrincipalAttributeEnumValues` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `principal_attribute_enum_value_id`, `name`, `display_name`, `description`, `created_by_user_id`, `modified_by_user_id`, `created_date`, and `modified_date`. Archive state is controlled via the `include_archived` field below, not via filter. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved enum values. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date`, `modified_date`, and `display_name`. If left empty, items are ordered by `created_date` in descending order (newest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "display\_name,created\_date desc" | | include\_archived | bool | | Whether to include archived enum values. Defaults to false. | ### ListPrincipalAttributeEnumValuesResponse | Field | Type | Label | Description | | :--------------------------------- | :---------------------------------------------------------- | :------- | :---------- | | principal\_attribute\_enum\_values | [PrincipalAttributeEnumValue](#principalattributeenumvalue) | repeated | | | next\_page\_token | string | | | ### ListPrincipalAttributeKeyValuesRequest ListPrincipalAttributeKeyValuesRequest is used to list principal attribute values for a given principal attribute key with the provided filter. | Field | Type | Label | Description | | :---------------------------- | :------------------------------------------------------------------ | :---- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | principal\_attribute\_key\_id | string | | The id of the principal attribute key to list values for. | | principal\_type | [PrincipalAttributePrincipalType](#principalattributeprincipaltype) | | | | page\_size | uint32 | | The maximum number of principal attribute values to return. The service may return fewer than this value. If unspecified, at most 50 principal attribute values will be returned. The maximum value is 1000. Values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListPrincipalAttributeKeyValues` call. Provide this to retrieve a subsequent page of principal attribute values. When paginating, all other parameters provided to `ListPrincipalAttributeKeyValues` must match the previous call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are: 'principal\_attribute\_value\_id', 'principal\_attribute\_key\_id', 'principal\_attribute\_enum\_value\_id', 'number\_value', 'boolean\_value', 'created\_date', 'created\_by\_user\_id', 'principal\_id', and 'principal\_type' For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). For more information about the fields used for filtering, please refer to this definition. Optional. | | order\_by | string | | How to order the retrieved principal attribute values. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date` If left empty, items are ordered by `created_date` in ascending order (oldest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc" | | include\_archived | bool | | If true, include archived values. Defaults to false. Optional. | ### ListPrincipalAttributeKeyValuesResponse ListPrincipalAttributeKeyValuesResponse returns the list of principal attribute values from a ListPrincipalAttributeKeyValues call. | Field | Type | Label | Description | | :--------------------------- | :-------------------------------------------------- | :------- | :---------- | | principal\_attribute\_values | [PrincipalAttributeValue](#principalattributevalue) | repeated | | | next\_page\_token | string | | | ### ListPrincipalAttributeKeysRequest ListPrincipalAttributeKeysRequest is used to list principal attribute keys with the provided filter. | Field | Type | Label | Description | | :---------------- | :----- | :---- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of principal attribute keys to return. The service may return fewer than this value. If unspecified, at most 50 principal attribute keys will be returned. The maximum value is 1000. Values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListPrincipalAttributeKeys` call. Provide this to retrieve a subsequent page of principal attribute keys. When paginating, all other parameters provided to `ListPrincipalAttributeKeys` must match the previous call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are: 'principal\_attribute\_key\_id', 'display\_name', 'value\_type', 'created\_by\_user\_id', 'created\_date', 'modified\_by\_user\_id, 'modified\_date' For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). For more information about the fields used for filtering, please refer to this definition. Optional. | | order\_by | string | | How to order the retrieved principal attribute keys. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date`, 'modified\_date', 'display\_name', 'principal\_attribute\_key\_id', 'value\_type', 'description' If left empty, items are ordered by `created_date` in ascending order (oldest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | | organization\_id | string | | | | include\_archived | bool | | If true, includes archived keys. Defaulta to false. Optional. | ### ListPrincipalAttributeKeysResponse ListPrincipalAttributeKeysResponse returns the list of principal attribute keys from a ListPrincipalAttributeKeys call. | Field | Type | Label | Description | | :------------------------- | :---------------------------------------------- | :------- | :---------- | | principal\_attribute\_keys | [PrincipalAttributeKey](#principalattributekey) | repeated | | | next\_page\_token | string | | | ### ListPrincipalAttributeValuesRequest ListPrincipalAttributeValuesRequest is used to list principal attribute values with the provided filter. | Field | Type | Label | Description | | :---------------- | :------------------------------------------------------------------ | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | principal\_type | [PrincipalAttributePrincipalType](#principalattributeprincipaltype) | | | | page\_size | uint32 | | The maximum number of principal attribute values to return. The service may return fewer than this value. If unspecified, at most 50 principal attribute values will be returned. The maximum value is 1000. Values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListPrincipalAttributeValues` call. Provide this to retrieve a subsequent page of principal attribute values. When paginating, all other parameters provided to `ListPrincipalAttributeValues` must match the previous call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are: 'principal\_attribute\_value\_id', 'principal\_attribute\_key\_id', 'principal\_attribute\_enum\_value\_id', 'number\_value', 'boolean\_value', 'created\_date', 'created\_by\_user\_id', 'principal\_id', and 'principal\_type'. Archive state is controlled via the `include_archived` field below, not via filter. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). For more information about the fields used for filtering, please refer to this definition. Optional. | | order\_by | string | | How to order the retrieved principal attribute values. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date` If left empty, items are ordered by `created_date` in ascending order (oldest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc" | | include\_archived | bool | | If true, include archived values. Defaults to false. Optional. | ### ListPrincipalAttributeValuesResponse ListPrincipalAttributeValuesResponse returns the list of principal attribute values from a ListPrincipalAttributeValues call. | Field | Type | Label | Description | | :--------------------------- | :-------------------------------------------------- | :------- | :---------- | | principal\_attribute\_values | [PrincipalAttributeValue](#principalattributevalue) | repeated | | | next\_page\_token | string | | | ### PrincipalAttributeEnumValue Represents a possible enumerable value for ENUM type principal attribute keys. Users can add new enum values as needed. | Field | Type | Label | Description | | :------------------------------------ | :------------------------ | :---- | :------------------------------------------------------------------------------------------------------------------ | | principal\_attribute\_enum\_value\_id | string | | | | principal\_attribute\_key\_id | string | | | | display\_name | string | | | | description | string | | | | created\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_date | google.protobuf.Timestamp | | | | modified\_by\_user\_id | string | | | | archived\_date | google.protobuf.Timestamp | | | | is\_archived | bool | | Whether or not the principal attribute enum value is archived. This is inferred from whether archived\_date is set. | ### PrincipalAttributeEnumValueIdList | Field | Type | Label | Description | | :---- | :----- | :------- | :---------- | | ids | string | repeated | | ### PrincipalAttributeKey | Field | Type | Label | Description | | :---------------------------- | :---------------------------------------------------------- | :---- | :----------------------------------------------------------------------------------------------------------- | | principal\_attribute\_key\_id | string | | | | organization\_id | string | | | | display\_name | string | | | | description | string | | | | type | [PrincipalAttributeValueType](#principalattributevaluetype) | | | | created\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_date | google.protobuf.Timestamp | | | | modified\_by\_user\_id | string | | | | archived\_date | google.protobuf.Timestamp | | | | is\_archived | bool | | Whether or not the principal attribute key is archived. This is inferred from whether archived\_date is set. | ### PrincipalAttributeValue | Field | Type | Label | Description | | :------------------------------------------------- | :------------------------------------------------------------------ | :---- | :------------------------------------------------------------------------------------------------------------- | | principal\_attribute\_value\_id | string | | | | principal\_attribute\_key\_id | string | | | | principal\_id | string | | The ID of the user or user group this value is assigned to. | | principal\_type | [PrincipalAttributePrincipalType](#principalattributeprincipaltype) | | | | organization\_id | string | | | | oneof value. principal\_attribute\_enum\_value\_id | string | | | | oneof value. number\_value | int64 | | | | oneof value. boolean\_value | bool | | | | created\_by\_user\_id | string | | | | created\_date | google.protobuf.Timestamp | | | | archived\_date | google.protobuf.Timestamp | | | | is\_archived | bool | | Whether or not the principal attribute value is archived. This is inferred from whether archived\_date is set. | | key | [PrincipalAttributeKey](#principalattributekey) | | The full principal attribute key is populated in the response. | | enum\_value\_details | [PrincipalAttributeEnumValue](#principalattributeenumvalue) | | Populated in responses with full enum value details. | ### UnarchivePrincipalAttributeEnumValueRequest | Field | Type | Label | Description | | :------------------------------------ | :----- | :---- | :---------- | | principal\_attribute\_enum\_value\_id | string | | | ### UnarchivePrincipalAttributeEnumValueResponse *This message has no fields.* ### UnarchivePrincipalAttributeKeysRequest UnarchivePrincipalAttributeKeysRequest is used to batch unarchive principal attribute keys by id. | Field | Type | Label | Description | | :----------------------------- | :----- | :------- | :---------- | | principal\_attribute\_key\_ids | string | repeated | | ### UnarchivePrincipalAttributeKeysResponse *This message has no fields.* ### UnarchivePrincipalAttributeValuesRequest UnarchivePrincipalAttributeValuesRequest is used to batch unarchive principal attribute values by id. | Field | Type | Label | Description | | :------------------------------- | :------------------------------------------------------------------ | :------- | :---------- | | principal\_attribute\_value\_ids | string | repeated | | | principal\_type | [PrincipalAttributePrincipalType](#principalattributeprincipaltype) | | | ### UnarchivePrincipalAttributeValuesResponse *This message has no fields.* ### UpdatePrincipalAttributeEnumValueRequest | Field | Type | Label | Description | | :------------------------------------ | :------------------------------------------------------ | :---- | :---------------------------------------------------------------------------------------------------------- | | principal\_attribute\_enum\_value\_id | string | | | | display\_name | string | | | | description | string | | | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The list of fields to be updated. The fields available to be updated are `description` and `archived_date`. | ### UpdatePrincipalAttributeEnumValueResponse | Field | Type | Label | Description | | :-------------------------------- | :---------------------------------------------------------- | :---- | :---------- | | principal\_attribute\_enum\_value | [PrincipalAttributeEnumValue](#principalattributeenumvalue) | | | ### UpdatePrincipalAttributeKeyRequest UpdatePrincipalAttributeKeyRequest is used to update an existing principal attribute key. | Field | Type | Label | Description | | :---------------------------- | :------------------------------------------------------ | :---- | :-------------------------------------------------------------------------------------- | | principal\_attribute\_key\_id | string | | | | display\_name | string | | | | description | string | | | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The list of fields to be updated. The fields available to be updated are 'description'. | ### UpdatePrincipalAttributeKeyResponse UpdatePrincipalAttributeKeyResponse returns the principal attribute key from a UpdatePrincipalAttributeKey call. | Field | Type | Label | Description | | :------------------------ | :---------------------------------------------- | :---- | :---------- | | principal\_attribute\_key | [PrincipalAttributeKey](#principalattributekey) | | | ## Enums *Allowed constant values used in message fields.* ### PrincipalAttributePrincipalType PrincipalAttributePrincipalType enumerates the supported principal types for principal attribute values. | Name | Number | Description | | :------------------------------------------------- | :----- | :---------- | | PRINCIPAL\_ATTRIBUTE\_PRINCIPAL\_TYPE\_UNSPECIFIED | 0 | | | PRINCIPAL\_ATTRIBUTE\_PRINCIPAL\_TYPE\_USER | 1 | | | PRINCIPAL\_ATTRIBUTE\_PRINCIPAL\_TYPE\_USER\_GROUP | 2 | | ### PrincipalAttributeValueType PrincipalAttributeValueType enumerates the supported value types for a principal attribute key. | Name | Number | Description | | :----------------------------------------------- | :----- | :---------- | | PRINCIPAL\_ATTRIBUTE\_VALUE\_TYPE\_UNSPECIFIED | 0 | | | PRINCIPAL\_ATTRIBUTE\_VALUE\_TYPE\_ENUM | 1 | | | PRINCIPAL\_ATTRIBUTE\_VALUE\_TYPE\_BOOLEAN | 2 | | | PRINCIPAL\_ATTRIBUTE\_VALUE\_TYPE\_NUMBER | 3 | | | PRINCIPAL\_ATTRIBUTE\_VALUE\_TYPE\_SET\_OF\_ENUM | 4 | | # protobuf_descriptors Source: https://docs.siftstack.com/api/reference/protocol-buffers/protobuf_descriptors sift/protobuf_descriptors/v2/protobuf_descriptors.proto ## Services *RPC methods exposed by this API.* ### ProtobufDescriptorService | Method | Request | Response | Description | | :----------------------------------- | :------------------------------------------------------------------------------------------ | :-------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------- | | AddProtobufDescriptor | [AddProtobufDescriptorRequest](#addprotobufdescriptorrequest) | [AddProtobufDescriptorResponse](#addprotobufdescriptorresponse) | Used to register a protobuf message to be ingested. | | CheckProtobufDescriptorCompatibility | [CheckProtobufDescriptorCompatibilityRequest](#checkprotobufdescriptorcompatibilityrequest) | [CheckProtobufDescriptorCompatibilityResponse](#checkprotobufdescriptorcompatibilityresponse) | Used to check if a protobuf descriptor is compatible with the existing descriptors. | | DeleteProtobufDescriptors | [DeleteProtobufDescriptorsRequest](#deleteprotobufdescriptorsrequest) | [DeleteProtobufDescriptorsResponse](#deleteprotobufdescriptorsresponse) | Delete protobuf descriptors of that match the provided `namespace` and `message_type_full_name`. | | ListProtobufDescriptors | [ListProtobufDescriptorsRequest](#listprotobufdescriptorsrequest) | [ListProtobufDescriptorsResponse](#listprotobufdescriptorsresponse) | Retrieve protobuf descriptors using an optional filter. | ## Messages *Data models used across requests/responses.* ### AddProtobufDescriptorRequest | Field | Type | Label | Description | | :----------------------------- | :---------------------------------------- | :---- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | protobuf\_descriptor | [ProtobufDescriptor](#protobufdescriptor) | | | | force\_duplicate\_registration | bool | | If set to true, the service will ignore checks that this descriptor has already been registered and will ensure that it is registered as the latest proto descriptor for the message type. | ### AddProtobufDescriptorResponse | Field | Type | Label | Description | | :------------------- | :---------------------------------------- | :---- | :---------- | | protobuf\_descriptor | [ProtobufDescriptor](#protobufdescriptor) | | | ### CheckProtobufDescriptorCompatibilityRequest | Field | Type | Label | Description | | :------------------- | :---------------------------------------- | :---- | :---------- | | protobuf\_descriptor | [ProtobufDescriptor](#protobufdescriptor) | | | ### CheckProtobufDescriptorCompatibilityResponse | Field | Type | Label | Description | | :----------------------------------------- | :------------------------------------------------------ | :------- | :---------- | | is\_valid | bool | | | | incompatible\_protobuf\_descriptor\_fields | [IncompatibleProtobufField](#incompatibleprotobuffield) | repeated | | ### DeleteProtobufDescriptorsRequest | Field | Type | Label | Description | | :------------------------ | :----- | :---- | :-------------- | | message\_type\_full\_name | string | | **Deprecated.** | | namespace | string | | **Deprecated.** | | organization\_id | string | | | | protobuf\_descriptor\_id | string | | | ### DeleteProtobufDescriptorsResponse *This message has no fields.* ### IncompatibleProtobufField | Field | Type | Label | Description | | :----------------------- | :----- | :---- | :---------- | | protobuf\_descriptor\_id | string | | | | message\_full\_name | string | | | | desired\_field\_name | string | | | | current\_field\_name | string | | | | field\_number | string | | | | reason | string | | | | details | string | | | | field\_kind | string | | | ### ListProtobufDescriptorsRequest The request for a call to `ProtobufDescriptorService_ListProtobufDescriptors` to retrieve protobuf descriptors. | Field | Type | Label | Description | | :---------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of protobuf descriptors to return. The service may return fewer than this value. If unspecified, at most 50 protobuf descriptors will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. | | page\_token | string | | A page token, received from a previous `ListProtobufDescriptors` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListProtobufDescriptors` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `protobuf_descriptor_id`, `proto_file_name`, `namespace`, and `message_type_full_name`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved protobuf descriptors. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date`, `modified_date`, and `message_type_full_name` and `namespace`. If left empty, items are ordered by `created_date` in ascending order (oldest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | ### ListProtobufDescriptorsResponse The response of a call to `ProtobufDescriptorService_ListProtobufDescriptors`. | Field | Type | Label | Description | | :-------------------- | :---------------------------------------- | :------- | :---------- | | protobuf\_descriptors | [ProtobufDescriptor](#protobufdescriptor) | repeated | | | next\_page\_token | string | | | ### ProtobufDescriptor | Field | Type | Label | Description | | :------------------------ | :------------------------ | :---- | :---------- | | message\_type\_full\_name | string | | | | file\_descriptor\_set | bytes | | | | proto\_file\_name | string | | | | namespace | string | | | | protobuf\_descriptor\_id | string | | | | created\_date | google.protobuf.Timestamp | | | ## Enums *Allowed constant values used in message fields.* # remote_files Source: https://docs.siftstack.com/api/reference/protocol-buffers/remote_files sift/remote_files/v1/remote_files.proto ## Services *RPC methods exposed by this API.* ### RemoteFileService | Method | Request | Response | Description | | :----------------------- | :------------------------------------------------------------------ | :-------------------------------------------------------------------- | :----------------------------------------------------------------------------------------- | | GetRemoteFile | [GetRemoteFileRequest](#getremotefilerequest) | [GetRemoteFileResponse](#getremotefileresponse) | Retrieve a remote file. | | CreateRemoteFile | [CreateRemoteFileRequest](#createremotefilerequest) | [CreateRemoteFileResponse](#createremotefileresponse) | Create a remote file. Note that this does not perform the actual file upload. | | ListRemoteFiles | [ListRemoteFilesRequest](#listremotefilesrequest) | [ListRemoteFilesResponse](#listremotefilesresponse) | List remote files. | | UpdateRemoteFile | [UpdateRemoteFileRequest](#updateremotefilerequest) | [UpdateRemoteFileResponse](#updateremotefileresponse) | Updates an existing remote file using using the list of fields specified in `update_mask`. | | DeleteRemoteFile | [DeleteRemoteFileRequest](#deleteremotefilerequest) | [DeleteRemoteFileResponse](#deleteremotefileresponse) | Delete a remote file. | | BatchDeleteRemoteFiles | [BatchDeleteRemoteFilesRequest](#batchdeleteremotefilesrequest) | [BatchDeleteRemoteFilesResponse](#batchdeleteremotefilesresponse) | Batch deletes remote files. Each batch is limited to 1000 records. | | GetRemoteFileDownloadUrl | [GetRemoteFileDownloadUrlRequest](#getremotefiledownloadurlrequest) | [GetRemoteFileDownloadUrlResponse](#getremotefiledownloadurlresponse) | Gets a download URL for the remote file. | ## Messages *Data models used across requests/responses.* ### AudioMetadata | Field | Type | Label | Description | | :---------------- | :------------------------ | :---- | :---------- | | duration\_seconds | float | | | | timestamp | google.protobuf.Timestamp | | | ### BatchDeleteRemoteFilesRequest The request for a call to `RemoteFileService_BatchDeleteRemoteFiles` to delete remote files. | Field | Type | Label | Description | | :---------------- | :----- | :------- | :------------------------------------------------------ | | remote\_file\_ids | string | repeated | Up to 1000 remote file IDs can be provided per request. | ### BatchDeleteRemoteFilesResponse The response of a call to `RemoteFileService_BatchDeleteRemoteFiles`. *This message has no fields.* ### CreateRemoteFileRequest The request for a call to `RemoteFileService_CreateRemoteFile` to create a remote file. | Field | Type | Label | Description | | :------------------------------ | :---------------------------------------------------------------- | :------- | :--------------------------------------------------------------------------- | | file\_name | string | | | | entity\_id | string | | | | entity\_type | [EntityType](#entitytype) | | | | file\_mime\_type | string | | | | file\_content\_encoding | string | | | | file\_size | uint64 | | | | description | string | optional | | | organization\_id | string | | This field is only required if your user belongs to multiple organizations. | | oneof metadata. video\_metadata | [VideoMetadata](#videometadata) | | | | oneof metadata. image\_metadata | [ImageMetadata](#imagemetadata) | | | | oneof metadata. audio\_metadata | [AudioMetadata](#audiometadata) | | | | custom\_uuid | string | optional | A custom UUID used to generate the object key. Recommended to be left unset. | | metadata\_values | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | The metadata values associated with this remote file. | ### CreateRemoteFileResponse The response for a call to `RemoteFileService_CreateRemoteFile`. | Field | Type | Label | Description | | :----------- | :------------------------ | :---- | :---------- | | remote\_file | [RemoteFile](#remotefile) | | | ### DeleteRemoteFileRequest The request for a call to `RemoteFileService_DeleteRemoteFile` to delete a remote file. | Field | Type | Label | Description | | :--------------- | :----- | :---- | :---------- | | remote\_file\_id | string | | | ### DeleteRemoteFileResponse The response of a call to `RemoteFileService_DeleteRemoteFile`. *This message has no fields.* ### GetRemoteFileDownloadUrlRequest The request for a call to `RemoteFileService_GetRemoteFileDownloadUrl`. | Field | Type | Label | Description | | :--------------- | :----- | :---- | :---------- | | remote\_file\_id | string | | | ### GetRemoteFileDownloadUrlResponse The response of a call to `RemoteFileService_GetRemoteFileDownloadUrl`. | Field | Type | Label | Description | | :------------ | :----- | :---- | :---------- | | download\_url | string | | | ### GetRemoteFileRequest The request for a call to `RemoteFileService_GetRemoteFile` to retrieve a remote file; | Field | Type | Label | Description | | :--------------- | :----- | :---- | :---------- | | remote\_file\_id | string | | | ### GetRemoteFileResponse The response of a call to `RemoteFileService_GetRemoteFile`. | Field | Type | Label | Description | | :----------- | :------------------------ | :---- | :---------- | | remote\_file | [RemoteFile](#remotefile) | | | ### ImageMetadata | Field | Type | Label | Description | | :----- | :----- | :---- | :---------- | | height | uint32 | | | | width | uint32 | | | ### ListRemoteFilesRequest The request for a call to `RemoteFileService_ListRemoteFiles` to retrieve remote files. | Field | Type | Label | Description | | :--------------- | :----- | :---- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of remote files to return. The service may return fewer than this value. If unspecified, at most 50 remote files will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListRemoteFiles` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListRemoteFiles` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `remote_file_id`, `entity_id`, `entity_type`, `metadata`, and `file_name`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | organization\_id | string | | This field is only required if your user belongs to multiple organizations. | | order\_by | string | | How to order the retrieved reports. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `name`, `created_date` and `modified_date`. If left empty, items are ordered by `created_date` in descending order (newest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | ### ListRemoteFilesResponse The response of a call to `RemoteFileService_ListRemoteFilesResponse`. | Field | Type | Label | Description | | :---------------- | :------------------------ | :------- | :---------- | | remote\_files | [RemoteFile](#remotefile) | repeated | | | next\_page\_token | string | | | ### RemoteFile | Field | Type | Label | Description | | :------------------------------ | :---------------------------------------------------------------- | :------- | :---------- | | remote\_file\_id | string | | | | organization\_id | string | | | | entity\_id | string | | | | entity\_type | [EntityType](#entitytype) | | | | file\_name | string | | | | file\_mime\_type | string | | | | file\_content\_encoding | string | | | | storage\_key | string | | | | file\_size | uint64 | | | | description | string | optional | | | oneof metadata. video\_metadata | [VideoMetadata](#videometadata) | | | | oneof metadata. image\_metadata | [ImageMetadata](#imagemetadata) | | | | oneof metadata. audio\_metadata | [AudioMetadata](#audiometadata) | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | metadata\_values | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | | | remote\_file\_type | [RemoteFileType](#remotefiletype) | | | ### UpdateRemoteFileRequest The request for a call to `RemoteFileService_UpdateRemoteFile` to update a remote file. | Field | Type | Label | Description | | :----------- | :------------------------------------------------------ | :---- | :------------------------------------------------------------------------------------------------------------------------- | | remote\_file | [RemoteFile](#remotefile) | | The remote file to update. | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The list of fields to be updated. The fields available to be updated are `description`, `metadata_values`, and `metadata`. | ### UpdateRemoteFileResponse The response of a call to `RemoteFileService_UpdateRemoteFile`. | Field | Type | Label | Description | | :----------- | :------------------------ | :---- | :---------- | | remote\_file | [RemoteFile](#remotefile) | | | ### VideoMetadata | Field | Type | Label | Description | | :---------------- | :------------------------ | :---- | :---------- | | height | uint32 | | | | width | uint32 | | | | duration\_seconds | float | | | | timestamp | google.protobuf.Timestamp | | | ## Enums *Allowed constant values used in message fields.* ### EntityType | Name | Number | Description | | :------------------------------------------------ | :----- | :---------------------------------------------------------------------------------------------------------- | | ENTITY\_TYPE\_UNSPECIFIED | 0 | | | ENTITY\_TYPE\_RUN | 1 | | | ENTITY\_TYPE\_ANNOTATION | 2 | | | ENTITY\_TYPE\_ASSET | 3 | | | ENTITY\_TYPE\_ANNOTATION\_LOG | 4 | | | ENTITY\_TYPE\_TEST\_REPORT | 5 | | | ENTITY\_TYPE\_TEST\_STEP | 6 | | | ENTITY\_TYPE\_CANVAS\_VERSION | 7 | | | ENTITY\_TYPE\_CANVAS\_CELL\_EXECUTION\_ATTACHMENT | 8 | UI evidence files attached to a cell execution on a canvas report. | | ENTITY\_TYPE\_CANVAS\_CELL\_EXECUTION\_OUTPUT | 9 | Reserved for a future cell-output upload path (not used by the report attachment UI). | | ENTITY\_TYPE\_ARTIFACT\_VERSION | 10 | Bytes of one artifact version (sift.artifacts.v1.ArtifactService); entity\_id is the artifact\_version\_id. | ### RemoteFileType | Name | Number | Description | | :------------------------------- | :----- | :--------------------------------------------------------- | | REMOTE\_FILE\_TYPE\_UNSPECIFIED | 0 | | | REMOTE\_FILE\_TYPE\_TELEMETRY | 1 | Data import / telemetry (internal: created by import job). | | REMOTE\_FILE\_TYPE\_IMAGE | 2 | | | REMOTE\_FILE\_TYPE\_VIDEO | 3 | | | REMOTE\_FILE\_TYPE\_AUDIO | 4 | | | REMOTE\_FILE\_TYPE\_TEST\_REPORT | 5 | | # report_templates Source: https://docs.siftstack.com/api/reference/protocol-buffers/report_templates sift/report_templates/v1/report_templates.proto ## Services *RPC methods exposed by this API.* ### ReportTemplateService | Method | Request | Response | Description | | :------------------- | :---------------------------------------------------------- | :------------------------------------------------------------ | :--------------------------------------------------------------------------------------- | | GetReportTemplate | [GetReportTemplateRequest](#getreporttemplaterequest) | [GetReportTemplateResponse](#getreporttemplateresponse) | Retrieve a report template. | | CreateReportTemplate | [CreateReportTemplateRequest](#createreporttemplaterequest) | [CreateReportTemplateResponse](#createreporttemplateresponse) | Create a report template. | | ListReportTemplates | [ListReportTemplatesRequest](#listreporttemplatesrequest) | [ListReportTemplatesResponse](#listreporttemplatesresponse) | List report templates. | | UpdateReportTemplate | [UpdateReportTemplateRequest](#updatereporttemplaterequest) | [UpdateReportTemplateResponse](#updatereporttemplateresponse) | Updates an existing report template using the list of fields specified in `update_mask`. | ## Messages *Data models used across requests/responses.* ### CreateReportTemplateRequest The request of a call to `ReportTemplateService_CreateReportTemplate` to create a report template. | Field | Type | Label | Description | | :------------------------------------------ | :------------------------------------------------------------------------------ | :------- | :-------------------------------------------------------------------------------- | | name | string | | | | client\_key | string | optional | | | description | string | optional | | | tag\_names | string | repeated | | | organization\_id | string | | `organization_id` is only required if your user belongs to multiple organizations | | oneof rule\_identifiers. rule\_ids | [CreateReportTemplateRequestRuleIds](#createreporttemplaterequestruleids) | | | | oneof rule\_identifiers. rule\_client\_keys | [CreateReportTemplateRequestClientKeys](#createreporttemplaterequestclientkeys) | | | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | | ### CreateReportTemplateRequestClientKeys Initial template rule order follows server resolution of keys to rules (not client-defined per-key ordering). | Field | Type | Label | Description | | :----------------- | :----- | :------- | :---------- | | rule\_client\_keys | string | repeated | | ### CreateReportTemplateRequestRuleIds Initial rule order on the new template: first `rule_id` is `display_order` 0, second is 1, etc. | Field | Type | Label | Description | | :-------- | :----- | :------- | :---------- | | rule\_ids | string | repeated | | ### CreateReportTemplateResponse The response of a call to `ReportTemplateService_CreateReportTemplate` to create a report template. | Field | Type | Label | Description | | :--------------- | :-------------------------------- | :---- | :---------- | | report\_template | [ReportTemplate](#reporttemplate) | | | ### GetReportTemplateRequest The request for a call to `ReportTemplateService_GetReportTemplate` to retrieve a report template. If `report_template_id` is provided then all other arguments will be ignored. The argument `report_template_id` should not be used together with `client_key`. The `organization_id` argument is only required if using `client_key` and the user belongs to multiple organizations. | Field | Type | Label | Description | | :------------------- | :----- | :---- | :---------- | | report\_template\_id | string | | | | client\_key | string | | | | organization\_id | string | | | ### GetReportTemplateResponse The request of a call to `ReportTemplateService_GetReportTemplate` to retrieve a report template. | Field | Type | Label | Description | | :--------------- | :-------------------------------- | :---- | :---------- | | report\_template | [ReportTemplate](#reporttemplate) | | | ### ListReportTemplatesRequest The request for a call to `ReportTemplateService_ListReportTemplates` to retrieve report templates. | Field | Type | Label | Description | | :---------------- | :----- | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of report templates to return. The service may return fewer than this value. If unspecified, at most 50 report templates will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListReportTemplates` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListReportTemplates` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `report_template_id`, `tag_id`, `tag_name`, `client_key`, `metadata`, `name` and 'is\_archived'. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | organization\_id | string | | This field is only required if your user belongs to multiple organizations. | | include\_archived | bool | | **Deprecated.** Deprecated. Use `filter` instead. | | order\_by | string | | How to order the retrieved report templates. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date` and `modified_date`. If left empty, items are ordered by `created_date` in descending order (newest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | ### ListReportTemplatesResponse The response of a call to `ReportTemplateService_ListReportTemplatesResponse`. | Field | Type | Label | Description | | :---------------- | :-------------------------------- | :------- | :---------- | | report\_templates | [ReportTemplate](#reporttemplate) | repeated | | | next\_page\_token | string | | | ### ReportTemplate | Field | Type | Label | Description | | :--------------------- | :---------------------------------------------------------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | report\_template\_id | string | | | | organization\_id | string | | | | client\_key | string | optional | | | name | string | | | | description | string | optional | | | archived\_date | google.protobuf.Timestamp | optional | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | rules | [ReportTemplateRule](#reporttemplaterule) | repeated | Rules on this template. On responses, sort by each rule's `display_order` ascending for execution order. On writes, if `display_order` is omitted on a rule, that rule's position follows the slice order of `rules` (same as explicit orders 0..n-1). | | tags | [ReportTemplateTag](#reporttemplatetag) | repeated | | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | | | is\_archived | bool | | Whether the report template is archived. This is inferred from whether archived\_date is set. | ### ReportTemplateRule | Field | Type | Label | Description | | :-------------------- | :----- | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | rule\_id | string | | | | rule\_version\_id | string | | | | rule\_version\_number | uint32 | | | | client\_key | string | | | | display\_order | uint32 | optional | Zero-based order for this rule on the template. Copied to `ReportRuleSummary.display_order` when creating a report from the template. Lower values indicate earlier position in the template and on generated reports. | Optional on writes (e.g. `UpdateReportTemplate`): if omitted, servers use the order of entries in `ReportTemplate.rules` (first entry is earliest). On reads, this field is always populated. | ### ReportTemplateTag | Field | Type | Label | Description | | :-------- | :----- | :---- | :---------- | | tag\_name | string | | | ### UpdateReportTemplateRequest The request for a call to `ReportTemplateService_UpdateReportTemplate` to update a report template. When updating tags or rules, the update will perform a full replace. Additionally, when updating rules, only the rule ID or the rule client key is required, but it is okay to provide both. If some rules contain only client keys and others only rule IDs, they will be consolidated. | Field | Type | Label | Description | | :--------------- | :------------------------------------------------------ | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------- | | report\_template | [ReportTemplate](#reporttemplate) | | The report template to update. | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The list of fields to be updated. The fields available to be updated are `name`, `archived_date`, `is_archived`, `description`, `tags`, `rules`, and `metadata`. | ### UpdateReportTemplateResponse The response of a call to `ReportTemplateService_UpdateReportTemplate`. | Field | Type | Label | Description | | :--------------- | :-------------------------------- | :---- | :---------- | | report\_template | [ReportTemplate](#reporttemplate) | | | ## Enums *Allowed constant values used in message fields.* # reports Source: https://docs.siftstack.com/api/reference/protocol-buffers/reports sift/reports/v1/reports.proto ## Services *RPC methods exposed by this API.* ### ReportService Report access is gated on the parent run's view\_details (RESOURCE\_TYPE\_RUN), not on RESOURCE\_TYPE\_REPORT (which the policy evaluation service does not yet support). RPCs that have a run id directly on the request use inbound\_policy\_enforcement; RPCs that resolve the run via a DB lookup (e.g. report\_id -> report -> run\_id) use manual\_policy\_enforcement and do the check in the handler. See web-service/authorization/authorization.go for the helpers. | Method | Request | Response | Description | | :------------------------------- | :---------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GetReport | [GetReportRequest](#getreportrequest) | [GetReportResponse](#getreportresponse) | Retrieve a report. | | CreateReport | [CreateReportRequest](#createreportrequest) | [CreateReportResponse](#createreportresponse) | Deprecated - use RuleEvaluationService instead. | | UpdateReport | [UpdateReportRequest](#updatereportrequest) | [UpdateReportResponse](#updatereportresponse) | Update a report. | | ListReports | [ListReportsRequest](#listreportsrequest) | [ListReportsResponse](#listreportsresponse) | List reports. | | RerunReport | [RerunReportRequest](#rerunreportrequest) | [RerunReportResponse](#rerunreportresponse) | Rerunning a report will create a new report with the same rule versions and run as the original report and run the evaluation again using the most up-to-date set of data. | | CancelReport | [CancelReportRequest](#cancelreportrequest) | [CancelReportResponse](#cancelreportresponse) | Canceling a report will stop the evaluation of the report and mark it as canceled. Any results that have been calculated up to the point of cancellation will be saved. | | ListReportRuleSummaries | [ListReportRuleSummariesRequest](#listreportrulesummariesrequest) | [ListReportRuleSummariesResponse](#listreportrulesummariesresponse) | List paginated rule summaries for a report. | | ListReportMetadataValues | [ListReportMetadataValuesRequest](#listreportmetadatavaluesrequest) | [ListReportMetadataValuesResponse](#listreportmetadatavaluesresponse) | List paginated metadata values for a report. | | ListReportsWithCumulativeSummary | [ListReportsWithCumulativeSummaryRequest](#listreportswithcumulativesummaryrequest) | [ListReportsWithCumulativeSummaryResponse](#listreportswithcumulativesummaryresponse) | List reports with cumulative summary. | ## Messages *Data models used across requests/responses.* ### CancelReportRequest | Field | Type | Label | Description | | :--------- | :----- | :---- | :---------- | | report\_id | string | | | ### CancelReportResponse no response fields *This message has no fields.* ### CreateReportFromReportTemplateRequest Deprecated - use RuleEvaluationService instead. Report rule lines use each template rule's `display_order` from `ReportTemplateRule` at creation time. | Field | Type | Label | Description | | :------------------- | :----- | :---- | :---------- | | report\_template\_id | string | | | ### CreateReportFromRulesRequest Deprecated - use RuleEvaluationService instead. How rules are ordered on the created report depends on `rule_identifiers`: list order for `rule_ids`, or server resolution order for `rule_client_keys`. | Field | Type | Label | Description | | :------------------------------------------ | :---------------------------------------------------------------------- | :------- | :---------- | | name | string | | | | description | string | optional | | | tag\_names | string | repeated | | | oneof rule\_identifiers. rule\_ids | [CreateReportRequestRuleIds](#createreportrequestruleids) | | | | oneof rule\_identifiers. rule\_client\_keys | [CreateReportRequestClientKeys](#createreportrequestclientkeys) | | | | oneof rule\_identifiers. rule\_version\_ids | [CreateReportRequestRuleVersionIds](#createreportrequestruleversionids) | | | ### CreateReportRequest Deprecated - use RuleEvaluationService instead. | Field | Type | Label | Description | | :----------------------------------------------------- | :------------------------------------------------------------------------------ | :------- | :---------------------------------------------------------------------------------------------------------------- | | oneof request. report\_from\_report\_template\_request | [CreateReportFromReportTemplateRequest](#createreportfromreporttemplaterequest) | | | | oneof request. report\_from\_rules\_request | [CreateReportFromRulesRequest](#createreportfromrulesrequest) | | | | organization\_id | string | | | | run\_id | string | | | | name | string | optional | Override the name of the report. If not provided, the name will be generated based on the report template or run. | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | | ### CreateReportRequestClientKeys Deprecated - use RuleEvaluationService instead. Rule order on the created report follows the order in which the server resolves these keys to rules (not client-defined). | Field | Type | Label | Description | | :----------------- | :----- | :------- | :---------- | | rule\_client\_keys | string | repeated | | ### CreateReportRequestRuleIds Deprecated - use RuleEvaluationService instead. The order of `rule_ids` is the report rule order: first ID is `display_order` 0, second is 1, etc., on the created report. | Field | Type | Label | Description | | :-------- | :----- | :------- | :---------- | | rule\_ids | string | repeated | | ### CreateReportRequestRuleVersionIds Deprecated - use RuleEvaluationService instead. | Field | Type | Label | Description | | :----------------- | :----- | :------- | :---------- | | rule\_version\_ids | string | repeated | | ### CreateReportResponse Deprecated - use RuleEvaluationService instead. | Field | Type | Label | Description | | :----- | :---------------- | :---- | :---------- | | report | [Report](#report) | | | ### GetReportRequest The request for a call to `ReportService_GetReport` to retrieve a report template. | Field | Type | Label | Description | | :--------- | :----- | :---- | :---------- | | report\_id | string | | | ### GetReportResponse The request of a call to `ReportService_GetReport` to retrieve a report template. | Field | Type | Label | Description | | :----- | :---------------- | :---- | :---------- | | report | [Report](#report) | | | ### ListReportMetadataValuesRequest The request for a call to `ReportService_ListReportMetadataValues`. | Field | Type | Label | Description | | :---------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | report\_id | string | | The report whose metadata values to list. | | page\_size | uint32 | | The maximum number of metadata values to return. The service may return fewer than this value. If unspecified, at most 50 metadata values will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListReportMetadataValues` call. Provide this to retrieve the subsequent page. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `key_name`, `value_string`, `value_number`, `value_boolean`, `key_is_archived`, and `value_is_archived`. Optional. | ### ListReportMetadataValuesResponse The response of a call to `ReportService_ListReportMetadataValues`. | Field | Type | Label | Description | | :---------------- | :---------------------------------------------------------------- | :------- | :---------- | | metadata\_values | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | | | next\_page\_token | string | | | ### ListReportRuleSummariesRequest The request for a call to `ReportService_ListReportRuleSummaries`. | Field | Type | Label | Description | | :---------- | :----- | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | report\_id | string | | The report whose rule summaries to list. | | page\_size | uint32 | | The maximum number of rule summaries to return. The service may return fewer than this value. If unspecified, at most 50 rule summaries will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListReportRuleSummaries` call. Provide this to retrieve the subsequent page. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `rule_id`, `rule_version_id`, `asset_id`, `status`, `created_date`, and `modified_date`. Optional. | | order\_by | string | | How to order the retrieved rule summaries. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order by are `display_order`, `created_date`, and `modified_date`. If left empty, items are ordered by `display_order` ascending. | ### ListReportRuleSummariesResponse The response of a call to `ReportService_ListReportRuleSummaries`. | Field | Type | Label | Description | | :---------------------- | :-------------------------------------- | :------- | :---------- | | report\_rule\_summaries | [ReportRuleSummary](#reportrulesummary) | repeated | | | next\_page\_token | string | | | ### ListReportsRequest The request for a call to `ReportService_ListReports` to retrieve report. | Field | Type | Label | Description | | :--------------- | :----- | :---- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of reports to return. The service may return fewer than this value. If unspecified, at most 50 reports will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListReports` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListReports` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `report_id`, `report_template_id`, `tag_name`, `name`, `run_id`, `report_type`, `canvas_id`, `is_archived`, `archived_date`, `created_date`, `created_by_user_id`, `metadata`, `modified_date`, and `modified_by_user_id`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | organization\_id | string | | This field is only required if your user belongs to multiple organizations. | | order\_by | string | | How to order the retrieved reports. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `name`, `created_date` and `modified_date`. If left empty, items are ordered by `created_date` in descending order (newest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | ### ListReportsResponse The response of a call to `ReportService_ListReportsResponse`. | Field | Type | Label | Description | | :---------------- | :---------------- | :------- | :---------- | | reports | [Report](#report) | repeated | | | next\_page\_token | string | | | ### ListReportsWithCumulativeSummaryRequest The request for a call to `ReportService_ListReportsWithCumulativeSummary` to retrieve reports. | Field | Type | Label | Description | | :--------------- | :----- | :---- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of reports to return. The service may return fewer than this value. If unspecified, at most 50 reports will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListReportsWithCumulativeSummary` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListReportsWithCumulativeSummary` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `report_id`, `report_template_id`, `tag_name`, `name`, `run_id`, `report_type`, `canvas_id`, `is_archived`, `archived_date`, `created_date`, `created_by_user_id`, `metadata`, `modified_date`, and `modified_by_user_id`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | organization\_id | string | | This field is only required if your user belongs to multiple organizations. | | order\_by | string | | How to order the retrieved reports. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `name`, `created_date` and `modified_date`. If left empty, items are ordered by `created_date` in descending order (newest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | ### ListReportsWithCumulativeSummaryResponse The response of a call to `ReportService_ListReportsWithCumulativeSummaryResponse`. | Field | Type | Label | Description | | :---------------- | :---------------------------------------------------------- | :------- | :---------- | | reports | [ReportWithCumulativeSummary](#reportwithcumulativesummary) | repeated | | | next\_page\_token | string | | | ### Report | Field | Type | Label | Description | | :---------------------- | :------------------------------------------------------------------------------------ | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | report\_id | string | | | | report\_template\_id | string | | | | run\_id | string | | Populated for RULE\_EVALUATION reports (which are tied to a run). Empty string for CANVAS reports. Kept REQUIRED (rather than a wrapped optional) to mirror ReportWithCumulativeSummary and avoid rippling optionality through existing rule-report clients. | | organization\_id | string | | | | name | string | | | | description | string | optional | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | summaries | [ReportRuleSummary](#reportrulesummary) | repeated | One entry per rule line on this report. Sort by `display_order` ascending for the canonical evaluation / display sequence (clients may still group by status for UI). `display_order` is set when the report is created from a template or from rules. | | tags | [ReportTag](#reporttag) | repeated | | | rerun\_from\_report\_id | string | optional | | | job\_id | string | optional | | | archived\_date | google.protobuf.Timestamp | optional | | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | | | is\_archived | bool | | | | report\_type | [ReportType](#reporttype) | | Discriminates the report kind. Defaults to RULE\_EVALUATION for existing rows. | | canvas\_execution\_id | string | optional | For CANVAS reports, the id of the published canvas\_execution this report row is linked to (read-through from canvas\_executions.canvas\_execution\_id). Empty for RULE\_EVALUATION reports. Used by clients to route to the canvas detail page. | | canvas\_status | [sift.canvas.v1.CanvasCellExecutionStatus](#sift-canvas-v1-canvascellexecutionstatus) | optional | For CANVAS reports, the execution status read through from the linked canvas\_executions.status. Unset for RULE\_EVALUATION reports (whose status is conveyed via the per-rule `summaries` instead). | | canvas\_version\_id | string | optional | For CANVAS reports, the id of the canvas\_version the linked execution was run from (read-through from canvas\_executions.canvas\_version\_id). Empty for RULE\_EVALUATION reports. Used by clients to route to the canvas source and to re-run the report from the same version. | | canvas\_id | string | optional | For CANVAS reports, the id of the canvas the linked execution was published from (resolved through canvas\_versions.canvas\_id). Empty for RULE\_EVALUATION reports, whose equivalent grouping is `report_template_id`. Also the value matched by the `canvas_id` list filter. Resolve the canvas's display name by listing canvases filtered on the ids collected from a page of reports. | ### ReportCumulativeRuleSummary Aggregated annotation and rule-status counts across all rules in a report. Annotation counts (num\_annotations\_*) reflect the total number of annotations in each state summed over every rule version in the report. Rule counts (num\_rules\_*) reflect how many rule versions are in each execution status. | Field | Type | Label | Description | | :----------------------------------- | :----- | :---- | :--------------------------------------------------------------------- | | num\_annotations\_open | uint32 | | Total number of open (unresolved) annotations across all rules. | | num\_annotations\_failed | uint32 | | Total number of failed (flagged) annotations across all rules. | | num\_annotations\_passed | uint32 | | Total number of passed (resolved) annotations across all rules. | | num\_annotations\_total | uint32 | | Total number of annotations across all rules (open + failed + passed). | | num\_rules\_created | uint32 | | Number of rule versions in CREATED status. | | num\_rules\_live | uint32 | | Number of rule versions currently running (LIVE status). | | num\_rules\_finished | uint32 | | Number of rule versions that finished successfully. | | num\_rules\_failed | uint32 | | Number of rule versions that failed during execution. | | num\_rules\_canceled | uint32 | | Number of rule versions that were canceled. | | num\_rules\_error | uint32 | | Number of rule versions that encountered an error. | | num\_rules\_total | uint32 | | Total number of rule versions across all statuses. | | num\_of\_rules\_without\_annotations | uint32 | | Number of finished rule versions that produced no annotations. | ### ReportRuleStatusDetails | Field | Type | Label | Description | | :---------------------- | :------------------------------------------------------------------ | :---- | :---------- | | oneof details. created | [ReportRuleStatusDetailsCreated](#reportrulestatusdetailscreated) | | | | oneof details. live | [ReportRuleStatusDetailsLive](#reportrulestatusdetailslive) | | | | oneof details. finished | [ReportRuleStatusDetailsFinished](#reportrulestatusdetailsfinished) | | | | oneof details. failed | [ReportRuleStatusDetailsFailed](#reportrulestatusdetailsfailed) | | | | oneof details. canceled | [ReportRuleStatusDetailsCanceled](#reportrulestatusdetailscanceled) | | | | oneof details. error | [ReportRuleStatusDetailsError](#reportrulestatusdetailserror) | | | ### ReportRuleStatusDetailsCanceled *This message has no fields.* ### ReportRuleStatusDetailsCreated *This message has no fields.* ### ReportRuleStatusDetailsError | Field | Type | Label | Description | | :------------- | :----- | :------- | :---------- | | error\_message | string | | | | exit\_code | int32 | optional | | | stdout | string | optional | | | stderr | string | optional | | ### ReportRuleStatusDetailsFailed | Field | Type | Label | Description | | :------------- | :----- | :------- | :---------- | | error\_message | string | | | | exit\_code | int32 | optional | | | stdout | string | optional | | | stderr | string | optional | | ### ReportRuleStatusDetailsFinished | Field | Type | Label | Description | | :----- | :----- | :------- | :---------- | | stdout | string | optional | | | stderr | string | optional | | ### ReportRuleStatusDetailsLive *This message has no fields.* ### ReportRuleSummary | Field | Type | Label | Description | | :--------------------------- | :-------------------------------------------------- | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | rule\_id | string | | | | rule\_client\_key | string | | | | rule\_version\_id | string | | | | rule\_version\_number | uint32 | | | | report\_rule\_version\_id | string | | | | num\_open | uint32 | | | | num\_failed | uint32 | | | | num\_passed | uint32 | | | | status | [ReportRuleStatus](#reportrulestatus) | | | | status\_details | [ReportRuleStatusDetails](#reportrulestatusdetails) | | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | asset\_id | string | | | | deleted\_date | google.protobuf.Timestamp | | | | resolved\_family\_stats | [ResolvedFamilyStat](#resolvedfamilystat) | repeated | | | resolved\_alignment\_configs | [ResolvedAlignmentEntry](#resolvedalignmententry) | repeated | | | display\_order | uint32 | | Zero-based position of this rule line on the report. Copied from the report template rule's `display_order`, or from the position of `rule_id` in `CreateReportRequestRuleIds.rule_ids` when creating from explicit rule IDs. Lower values run first. | ### ReportTag | Field | Type | Label | Description | | :-------- | :----- | :---- | :---------- | | tag\_name | string | | | ### ReportWithCumulativeSummary ReportWithCumulativeSummary is a projection of `Report` that replaces the per-rule `summaries` list with a single `cumulative_summary` aggregated across all rules. It is returned by `ListReportsWithCumulativeSummary` to keep response sizes manageable when listing many reports. | Field | Type | Label | Description | | :---------------------- | :------------------------------------------------------------------------------------ | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | report\_id | string | | The unique identifier of the report. | | report\_template\_id | string | | The identifier of the report template this report was created from, if any. | | run\_id | string | | The identifier of the run associated with this report. | | organization\_id | string | | The organization this report belongs to. | | name | string | | The display name of the report. | | description | string | optional | An optional description of the report. | | created\_by\_user\_id | string | | The identifier of the user who created the report. | | modified\_by\_user\_id | string | | The identifier of the user who last modified the report. | | created\_date | google.protobuf.Timestamp | | When the report was created. | | modified\_date | google.protobuf.Timestamp | | When the report was last modified. | | cumulative\_summary | [ReportCumulativeRuleSummary](#reportcumulativerulesummary) | | Aggregated rule summary across all rules on this report. | | tags | [ReportTag](#reporttag) | repeated | Tags associated with this report. | | rerun\_from\_report\_id | string | optional | The identifier of the report this report was rerun from, if any. | | job\_id | string | optional | The identifier of the job that produced this report, if any. | | archived\_date | google.protobuf.Timestamp | optional | When the report was archived, if it has been archived. | | is\_archived | bool | | Whether the report has been archived. | | report\_type | [ReportType](#reporttype) | | Discriminates the report kind. Defaults to RULE\_EVALUATION for existing rows. | | canvas\_execution\_id | string | optional | For CANVAS reports, the id of the published canvas\_execution this report row is linked to (read-through from canvas\_executions.canvas\_execution\_id). Empty for RULE\_EVALUATION reports. Used by clients to route to the canvas detail page. | | canvas\_status | [sift.canvas.v1.CanvasCellExecutionStatus](#sift-canvas-v1-canvascellexecutionstatus) | optional | For CANVAS reports, the execution status read through from the linked canvas\_executions.status. Unset for RULE\_EVALUATION reports (whose status is conveyed via the `cumulative_summary` instead). | | canvas\_version\_id | string | optional | For CANVAS reports, the id of the canvas\_version the linked execution was run from (read-through from canvas\_executions.canvas\_version\_id). Empty for RULE\_EVALUATION reports. Used by clients to route to the canvas source and to re-run the report from the same version. | | canvas\_id | string | optional | For CANVAS reports, the id of the canvas the linked execution was published from (resolved through canvas\_versions.canvas\_id). Empty for RULE\_EVALUATION reports, whose equivalent grouping is `report_template_id`. Also the value matched by the `canvas_id` list filter. Resolve the canvas's display name by listing canvases filtered on the ids collected from a page of reports. | ### RerunReportRequest | Field | Type | Label | Description | | :--------- | :----- | :---- | :---------- | | report\_id | string | | | ### RerunReportResponse | Field | Type | Label | Description | | :--------- | :----- | :---- | :---------- | | job\_id | string | | | | report\_id | string | | | ### ResolvedAlignmentEntry | Field | Type | Label | Description | | :------------------ | :------------------------------------------------ | :------- | :---------- | | channel\_references | string | repeated | | | t0 | [ResolvedAlignmentPoint](#resolvedalignmentpoint) | | | | start\_time | [ResolvedAlignmentPoint](#resolvedalignmentpoint) | | | | end\_time | [ResolvedAlignmentPoint](#resolvedalignmentpoint) | | | ### ResolvedAlignmentPoint | Field | Type | Label | Description | | :----------------------------------------- | :---------------------------------------------------------------------------- | :---- | :---------- | | timestamp | google.protobuf.Timestamp | | | | oneof alignment\_config. run | [sift.families.v1.RunAlignment](#sift-families-v1-runalignment) | | | | oneof alignment\_config. annotation | [sift.families.v1.AnnotationAlignment](#sift-families-v1-annotationalignment) | | | | oneof alignment\_config. timestamp\_config | [sift.families.v1.TimestampAlignment](#sift-families-v1-timestampalignment) | | | ### ResolvedFamilyStat | Field | Type | Label | Description | | :--------------------------- | :----- | :---- | :---------- | | reference | string | | | | family\_id | string | | | | family\_version\_id | string | | | | family\_stat\_expression\_id | string | | | | family\_stat\_range\_id | string | | | ### UpdateReportRequest | Field | Type | Label | Description | | :----------- | :------------------------------------------------------ | :---- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | report | [Report](#report) | | The report to update. | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The list of fields to be updated. The fields available to be updated are `name`, `description`, `archived_date`, `is_archived`, and `metadata`. An empty `name` is ignored and the existing name is preserved. Including `description` in the mask with the field unset clears the description. | ### UpdateReportResponse no response fields *This message has no fields.* ## Enums *Allowed constant values used in message fields.* ### ReportRuleStatus | Name | Number | Description | | :-------------------------------- | :----- | :---------- | | REPORT\_RULE\_STATUS\_UNSPECIFIED | 0 | | | REPORT\_RULE\_STATUS\_CREATED | 1 | | | REPORT\_RULE\_STATUS\_LIVE | 2 | | | REPORT\_RULE\_STATUS\_FINISHED | 3 | | | REPORT\_RULE\_STATUS\_FAILED | 4 | | | REPORT\_RULE\_STATUS\_CANCELED | 5 | | | REPORT\_RULE\_STATUS\_ERROR | 6 | | ### ReportType ReportType discriminates the two kinds of report rows that share the unified `reports` surface. Rule-evaluation reports are tied to a run; canvas reports are tied to a published canvas\_execution. | Name | Number | Description | | :----------------------------- | :----- | :---------- | | REPORT\_TYPE\_UNSPECIFIED | 0 | | | REPORT\_TYPE\_RULE\_EVALUATION | 1 | | | REPORT\_TYPE\_CANVAS | 2 | | # resource_attribute Source: https://docs.siftstack.com/api/reference/protocol-buffers/resource_attribute sift/resource_attribute/v1/resource_attribute.proto ## Services *RPC methods exposed by this API.* ### ResourceAttributeService | Method | Request | Response | Description | | :---------------------------------------- | :---------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------ | :---------------------------------------------------------------------------------------------------------------------------- | | CreateResourceAttributeKey | [CreateResourceAttributeKeyRequest](#createresourceattributekeyrequest) | [CreateResourceAttributeKeyResponse](#createresourceattributekeyresponse) | | | GetResourceAttributeKey | [GetResourceAttributeKeyRequest](#getresourceattributekeyrequest) | [GetResourceAttributeKeyResponse](#getresourceattributekeyresponse) | | | ListResourceAttributeKeys | [ListResourceAttributeKeysRequest](#listresourceattributekeysrequest) | [ListResourceAttributeKeysResponse](#listresourceattributekeysresponse) | | | UpdateResourceAttributeKey | [UpdateResourceAttributeKeyRequest](#updateresourceattributekeyrequest) | [UpdateResourceAttributeKeyResponse](#updateresourceattributekeyresponse) | | | CheckResourceAttributeKeyArchiveImpact | [CheckResourceAttributeKeyArchiveImpactRequest](#checkresourceattributekeyarchiveimpactrequest) | [CheckResourceAttributeKeyArchiveImpactResponse](#checkresourceattributekeyarchiveimpactresponse) | | | ArchiveResourceAttributeKey | [ArchiveResourceAttributeKeyRequest](#archiveresourceattributekeyrequest) | [ArchiveResourceAttributeKeyResponse](#archiveresourceattributekeyresponse) | Archives a resource\_attribute key AND all its associated enum values AND all its associated resource-attributes. | | UnarchiveResourceAttributeKey | [UnarchiveResourceAttributeKeyRequest](#unarchiveresourceattributekeyrequest) | [UnarchiveResourceAttributeKeyResponse](#unarchiveresourceattributekeyresponse) | Unarchives a resource\_attribute key BUT NOT its associated enum values OR resource-attributes. | | BatchArchiveResourceAttributeKeys | [BatchArchiveResourceAttributeKeysRequest](#batcharchiveresourceattributekeysrequest) | [BatchArchiveResourceAttributeKeysResponse](#batcharchiveresourceattributekeysresponse) | Archives multiple resource\_attribute keys AND all their associated enum values AND all their associated resource-attributes. | | BatchUnarchiveResourceAttributeKeys | [BatchUnarchiveResourceAttributeKeysRequest](#batchunarchiveresourceattributekeysrequest) | [BatchUnarchiveResourceAttributeKeysResponse](#batchunarchiveresourceattributekeysresponse) | Unarchives multiple resource\_attribute keys BUT NOT their associated enum values OR resource-attributes. | | CreateResourceAttributeEnumValue | [CreateResourceAttributeEnumValueRequest](#createresourceattributeenumvaluerequest) | [CreateResourceAttributeEnumValueResponse](#createresourceattributeenumvalueresponse) | | | GetResourceAttributeEnumValue | [GetResourceAttributeEnumValueRequest](#getresourceattributeenumvaluerequest) | [GetResourceAttributeEnumValueResponse](#getresourceattributeenumvalueresponse) | | | ListResourceAttributeEnumValues | [ListResourceAttributeEnumValuesRequest](#listresourceattributeenumvaluesrequest) | [ListResourceAttributeEnumValuesResponse](#listresourceattributeenumvaluesresponse) | | | UpdateResourceAttributeEnumValue | [UpdateResourceAttributeEnumValueRequest](#updateresourceattributeenumvaluerequest) | [UpdateResourceAttributeEnumValueResponse](#updateresourceattributeenumvalueresponse) | | | ArchiveResourceAttributeEnumValue | [ArchiveResourceAttributeEnumValueRequest](#archiveresourceattributeenumvaluerequest) | [ArchiveResourceAttributeEnumValueResponse](#archiveresourceattributeenumvalueresponse) | Archives an enum value and migrates all resource-attributes with that value to a replacement value. | | UnarchiveResourceAttributeEnumValue | [UnarchiveResourceAttributeEnumValueRequest](#unarchiveresourceattributeenumvaluerequest) | [UnarchiveResourceAttributeEnumValueResponse](#unarchiveresourceattributeenumvalueresponse) | Unarchives an enum value BUT DOES NOT migrate resource-attributes with a replacement value back to the original value. | | BatchArchiveResourceAttributeEnumValues | [BatchArchiveResourceAttributeEnumValuesRequest](#batcharchiveresourceattributeenumvaluesrequest) | [BatchArchiveResourceAttributeEnumValuesResponse](#batcharchiveresourceattributeenumvaluesresponse) | Archives multiple enum values and migrates all resource-attributes with those values to their respective replacement values. | | BatchUnarchiveResourceAttributeEnumValues | [BatchUnarchiveResourceAttributeEnumValuesRequest](#batchunarchiveresourceattributeenumvaluesrequest) | [BatchUnarchiveResourceAttributeEnumValuesResponse](#batchunarchiveresourceattributeenumvaluesresponse) | Unarchives multiple enum values BUT DOES NOT migrate resource-attributes with a replacement value back to the original value. | | BatchCreateResourceAttributes | [BatchCreateResourceAttributesRequest](#batchcreateresourceattributesrequest) | [BatchCreateResourceAttributesResponse](#batchcreateresourceattributesresponse) | Creates resource-attributes for multiple entities with the same key-value pair. | | GetResourceAttribute | [GetResourceAttributeRequest](#getresourceattributerequest) | [GetResourceAttributeResponse](#getresourceattributeresponse) | | | ListResourceAttributes | [ListResourceAttributesRequest](#listresourceattributesrequest) | [ListResourceAttributesResponse](#listresourceattributesresponse) | | | ListResourceAttributesByEntity | [ListResourceAttributesByEntityRequest](#listresourceattributesbyentityrequest) | [ListResourceAttributesByEntityResponse](#listresourceattributesbyentityresponse) | Lists all resource-attributes for a specific entity. Excludes archived by default. | | BatchListResourceAttributesByEntity | [BatchListResourceAttributesByEntityRequest](#batchlistresourceattributesbyentityrequest) | [BatchListResourceAttributesByEntityResponse](#batchlistresourceattributesbyentityresponse) | Batch lists all resource-attributes for multiple entities. Excludes archived by default. | | ArchiveResourceAttribute | [ArchiveResourceAttributeRequest](#archiveresourceattributerequest) | [ArchiveResourceAttributeResponse](#archiveresourceattributeresponse) | | | UnarchiveResourceAttribute | [UnarchiveResourceAttributeRequest](#unarchiveresourceattributerequest) | [UnarchiveResourceAttributeResponse](#unarchiveresourceattributeresponse) | | | BatchArchiveResourceAttributes | [BatchArchiveResourceAttributesRequest](#batcharchiveresourceattributesrequest) | [BatchArchiveResourceAttributesResponse](#batcharchiveresourceattributesresponse) | Archives multiple resource-attributes. | | BatchUnarchiveResourceAttributes | [BatchUnarchiveResourceAttributesRequest](#batchunarchiveresourceattributesrequest) | [BatchUnarchiveResourceAttributesResponse](#batchunarchiveresourceattributesresponse) | Unarchives multiple resource-attributes. | ## Messages *Data models used across requests/responses.* ### ArchiveResourceAttributeEnumValueRequest | Field | Type | Label | Description | | :--------------------------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | archived\_enum\_value\_id | string | | | | replacement\_enum\_value\_id | string | | When the archived\_enum\_value\_id is archived all resource-attributes that reference it will be migrated to the replacement\_enum\_value\_id if provided. Otherwise, resource-attributes that reference it will be archived as well. | ### ArchiveResourceAttributeEnumValueResponse | Field | Type | Label | Description | | :----------------------------- | :---- | :---- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | resource\_attributes\_migrated | int32 | | Total number of resource-attributes migrated or archived by this operation. When a replacement enum value is provided, this represents attributes migrated to the new value. When no replacement is provided, this represents attributes that were archived. | ### ArchiveResourceAttributeKeyRequest | Field | Type | Label | Description | | :--------------------------- | :----- | :---- | :---------- | | resource\_attribute\_key\_id | string | | | ### ArchiveResourceAttributeKeyResponse *This message has no fields.* ### ArchiveResourceAttributeRequest | Field | Type | Label | Description | | :---------------------- | :----- | :---- | :---------- | | resource\_attribute\_id | string | | | ### ArchiveResourceAttributeResponse *This message has no fields.* ### BatchArchiveResourceAttributeEnumValuesRequest | Field | Type | Label | Description | | :----------------- | :------------------------------------------------------------------------------------------------------------------------------------ | :------- | :---------- | | archival\_requests | [BatchArchiveResourceAttributeEnumValuesRequest.EnumValueArchival](#batcharchiveresourceattributeenumvaluesrequest-enumvaluearchival) | repeated | | ### BatchArchiveResourceAttributeEnumValuesRequest.EnumValueArchival | Field | Type | Label | Description | | :--------------------------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | archived\_enum\_value\_id | string | | The enum value ID to archive. | | replacement\_enum\_value\_id | string | | When the archived\_enum\_value\_id is archived all resource-attributes that reference it will be migrated to the replacement\_enum\_value\_id if provided. Otherwise, resource-attributes that reference it will be archived as well. | ### BatchArchiveResourceAttributeEnumValuesResponse | Field | Type | Label | Description | | :------------------------------------ | :---- | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | total\_resource\_attributes\_migrated | int32 | | Total number of resource-attributes migrated or archived across all enum value operations. This includes both attributes migrated to replacement values and attributes archived without replacement. | ### BatchArchiveResourceAttributeKeysRequest | Field | Type | Label | Description | | :---------------------------- | :----- | :------- | :---------- | | resource\_attribute\_key\_ids | string | repeated | | ### BatchArchiveResourceAttributeKeysResponse *This message has no fields.* ### BatchArchiveResourceAttributesRequest | Field | Type | Label | Description | | :----------------------- | :----- | :------- | :---------- | | resource\_attribute\_ids | string | repeated | | ### BatchArchiveResourceAttributesResponse *This message has no fields.* ### BatchCreateResourceAttributesRequest ResourceAttribute RPC messages | Field | Type | Label | Description | | :------------------------------------------------- | :---------------------------------------------------------------------- | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | resource\_attribute\_key\_id | string | | | | oneof value. resource\_attribute\_enum\_value\_id | string | | For ENUM type: exactly one enum value ID. | | oneof value. resource\_attribute\_enum\_value\_ids | [ResourceAttributeEnumValueIdList](#resourceattributeenumvalueidlist) | | For SET\_OF\_ENUM type: one or more enum value IDs representing the complete desired set. Omitted enum values that are currently active for each entity+key will be archived. | | oneof value. boolean\_value | bool | | | | oneof value. number\_value | int64 | | | | entities | [ResourceAttributeEntityIdentifier](#resourceattributeentityidentifier) | repeated | | ### BatchCreateResourceAttributesResponse | Field | Type | Label | Description | | :------------------- | :-------------------------------------- | :------- | :---------- | | resource\_attributes | [ResourceAttribute](#resourceattribute) | repeated | | ### BatchListResourceAttributesByEntityRequest | Field | Type | Label | Description | | :---------------- | :---------------------------------------------------------------------- | :------- | :------------------------------------------------------------------ | | entities | [ResourceAttributeEntityIdentifier](#resourceattributeentityidentifier) | repeated | | | include\_archived | bool | | Whether to include archived resource-attributes. Defaults to false. | ### BatchListResourceAttributesByEntityResponse | Field | Type | Label | Description | | :------ | :-------------------------------------------------------------------------------------------------------------------------------------------- | :------- | :---------- | | results | [BatchListResourceAttributesByEntityResponse.EntityResourceAttributes](#batchlistresourceattributesbyentityresponse-entityresourceattributes) | repeated | | ### BatchListResourceAttributesByEntityResponse.EntityResourceAttributes | Field | Type | Label | Description | | :------------------- | :---------------------------------------------------------------------- | :------- | :-------------------------------------- | | entity | [ResourceAttributeEntityIdentifier](#resourceattributeentityidentifier) | | The entity the attributes belong to | | resource\_attributes | [ResourceAttribute](#resourceattribute) | repeated | All resource-attributes for this entity | ### BatchUnarchiveResourceAttributeEnumValuesRequest | Field | Type | Label | Description | | :------------------------------------ | :----- | :------- | :---------- | | resource\_attribute\_enum\_value\_ids | string | repeated | | ### BatchUnarchiveResourceAttributeEnumValuesResponse *This message has no fields.* ### BatchUnarchiveResourceAttributeKeysRequest | Field | Type | Label | Description | | :---------------------------- | :----- | :------- | :---------- | | resource\_attribute\_key\_ids | string | repeated | | ### BatchUnarchiveResourceAttributeKeysResponse *This message has no fields.* ### BatchUnarchiveResourceAttributesRequest | Field | Type | Label | Description | | :----------------------- | :----- | :------- | :---------- | | resource\_attribute\_ids | string | repeated | | ### BatchUnarchiveResourceAttributesResponse *This message has no fields.* ### CheckResourceAttributeKeyArchiveImpactRequest | Field | Type | Label | Description | | :--------------------------- | :----- | :---- | :---------- | | resource\_attribute\_key\_id | string | | | ### CheckResourceAttributeKeyArchiveImpactResponse | Field | Type | Label | Description | | :--------------------------------------------- | :---- | :---- | :----------------------------------------------------------------------------------------------- | | active\_resource\_attribute\_assignment\_count | int64 | | The number of active resource attribute assignments that will be affected by archiving this key. | ### CreateResourceAttributeEnumValueRequest ResourceAttribute Enum Value RPC messages | Field | Type | Label | Description | | :--------------------------- | :----- | :---- | :---------- | | resource\_attribute\_key\_id | string | | | | display\_name | string | | | | description | string | | | ### CreateResourceAttributeEnumValueResponse | Field | Type | Label | Description | | :------------------------------- | :-------------------------------------------------------- | :---- | :---------- | | resource\_attribute\_enum\_value | [ResourceAttributeEnumValue](#resourceattributeenumvalue) | | | ### CreateResourceAttributeKeyRequest ResourceAttribute Key RPC messages | Field | Type | Label | Description | | :-------------------- | :-------------------------------------------------------------------------------------------------------- | :------- | :-------------------------------------------------------------------------------------------- | | display\_name | string | | | | description | string | | | | type | [ResourceAttributeKeyType](#resourceattributekeytype) | | | | initial\_enum\_values | [CreateResourceAttributeKeyRequest.InitialEnumValue](#createresourceattributekeyrequest-initialenumvalue) | repeated | Optional initial enum values to create alongside the key. Only applicable for ENUM type keys. | ### CreateResourceAttributeKeyRequest.InitialEnumValue Nested message for initial enum values in create requests. | Field | Type | Label | Description | | :------------ | :----- | :---- | :---------- | | display\_name | string | | | | description | string | | | ### CreateResourceAttributeKeyResponse | Field | Type | Label | Description | | :----------------------- | :-------------------------------------------------------- | :------- | :------------------------------------------------------------------------------ | | resource\_attribute\_key | [ResourceAttributeKey](#resourceattributekey) | | | | enum\_values | [ResourceAttributeEnumValue](#resourceattributeenumvalue) | repeated | The enum values created alongside the key, if any were provided in the request. | ### GetResourceAttributeEnumValueRequest | Field | Type | Label | Description | | :----------------------------------- | :----- | :---- | :---------- | | resource\_attribute\_enum\_value\_id | string | | | ### GetResourceAttributeEnumValueResponse | Field | Type | Label | Description | | :------------------------------- | :-------------------------------------------------------- | :---- | :---------- | | resource\_attribute\_enum\_value | [ResourceAttributeEnumValue](#resourceattributeenumvalue) | | | ### GetResourceAttributeKeyRequest | Field | Type | Label | Description | | :--------------------------- | :----- | :---- | :---------- | | resource\_attribute\_key\_id | string | | | ### GetResourceAttributeKeyResponse | Field | Type | Label | Description | | :----------------------- | :-------------------------------------------- | :---- | :---------- | | resource\_attribute\_key | [ResourceAttributeKey](#resourceattributekey) | | | ### GetResourceAttributeRequest | Field | Type | Label | Description | | :---------------------- | :----- | :---- | :---------- | | resource\_attribute\_id | string | | | ### GetResourceAttributeResponse | Field | Type | Label | Description | | :------------------ | :-------------------------------------- | :---- | :---------- | | resource\_attribute | [ResourceAttribute](#resourceattribute) | | | ### ListResourceAttributeEnumValuesRequest | Field | Type | Label | Description | | :--------------------------- | :----- | :---- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | resource\_attribute\_key\_id | string | | | | page\_size | uint32 | | The maximum number of enum values to return. The service may return fewer than this value. If unspecified, at most 50 enum values will be returned. The maximum value is 100; values above 100 will be coerced to 100. | | page\_token | string | | A page token, received from a previous `ListResourceAttributeEnumValues` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListResourceAttributeEnumValues` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `resource_attribute_enum_value_id`, `name`, `description`, `created_by_user_id`, `modified_by_user_id`, `created_date`, and `modified_date`. Archive state is controlled via the `include_archived` field below, not via filter. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved enum values. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date`, `modified_date`, and `name`. If left empty, items are ordered by `created_date` in descending order (newest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "name,created\_date desc" | | include\_archived | bool | | Whether to include archived enum values. Defaults to false. | ### ListResourceAttributeEnumValuesResponse | Field | Type | Label | Description | | :-------------------------------- | :-------------------------------------------------------- | :------- | :---------- | | resource\_attribute\_enum\_values | [ResourceAttributeEnumValue](#resourceattributeenumvalue) | repeated | | | next\_page\_token | string | | | ### ListResourceAttributeKeysRequest | Field | Type | Label | Description | | :---------------- | :----- | :---- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of resource\_attribute keys to return. The service may return fewer than this value. If unspecified, at most 50 resource\_attribute keys will be returned. The maximum value is 100; values above 100 will be coerced to 100. | | page\_token | string | | A page token, received from a previous `ListResourceAttributeKeys` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListResourceAttributeKeys` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `resource_attribute_key_id`, `name`, `description`, `key_type`, and `created_date`. Archive state is controlled via the `include_archived` field below, not via filter. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved resource\_attribute keys. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date`, `modified_date`, and `name`. If left empty, items are ordered by `created_date` in descending order (newest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,name" | | include\_archived | bool | | Whether to include archived resource\_attribute keys. Defaults to false. | ### ListResourceAttributeKeysResponse | Field | Type | Label | Description | | :------------------------ | :-------------------------------------------- | :------- | :---------- | | resource\_attribute\_keys | [ResourceAttributeKey](#resourceattributekey) | repeated | | | next\_page\_token | string | | | ### ListResourceAttributesByEntityRequest | Field | Type | Label | Description | | :---------------- | :---------------------------------------------------------------------- | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | entity | [ResourceAttributeEntityIdentifier](#resourceattributeentityidentifier) | | | | include\_archived | bool | | Whether to include archived resource-attributes. Defaults to false. | | page\_size | uint32 | | The maximum number of resource-attributes to return. The service may return fewer than this value. If unspecified, at most 50 resource-attributes will be returned. The maximum value is 100; values above 100 will be coerced to 100. | | page\_token | string | | A page token, received from a previous `ListResourceAttributesByEntity` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListResourceAttributesByEntity` must match the call that provided the page token. | ### ListResourceAttributesByEntityResponse | Field | Type | Label | Description | | :------------------- | :-------------------------------------- | :------- | :---------- | | resource\_attributes | [ResourceAttribute](#resourceattribute) | repeated | | | next\_page\_token | string | | | ### ListResourceAttributesRequest | Field | Type | Label | Description | | :---------------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | page\_size | uint32 | | The maximum number of resource-attributes to return. The service may return fewer than this value. If unspecified, at most 50 resource-attributes will be returned. The maximum value is 100; values above 100 will be coerced to 100. | | page\_token | string | | A page token, received from a previous `ListResourceAttributes` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListResourceAttributes` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `resource_attribute_id`, `entity_id`, `entity_type`, `resource_attribute_key_id`, `resource_attribute_enum_value_id`, `boolean_value`, `number_value`, `created_by_user_id`, and `created_date`. Archive state is controlled via the `include_archived` field below, not via filter. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved resource-attributes. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date` and `entity.entity_id`. If left empty, items are ordered by `created_date` in descending order (newest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "entity.entity\_id,created\_date desc" | | include\_archived | bool | | Whether to include archived resource-attributes. Defaults to false. | ### ListResourceAttributesResponse | Field | Type | Label | Description | | :------------------- | :-------------------------------------- | :------- | :---------- | | resource\_attributes | [ResourceAttribute](#resourceattribute) | repeated | | | next\_page\_token | string | | | ### ResourceAttribute Represents the assignment of a resource\_attribute key-value pair to an entity (asset or channel). | Field | Type | Label | Description | | :------------------------------------------------ | :---------------------------------------------------------------------- | :---- | :------------------------------------------------------------------------------------------------------ | | resource\_attribute\_id | string | | | | organization\_id | string | | | | entity | [ResourceAttributeEntityIdentifier](#resourceattributeentityidentifier) | | | | resource\_attribute\_key\_id | string | | | | key | [ResourceAttributeKey](#resourceattributekey) | | Populated in responses with full key details. | | oneof value. resource\_attribute\_enum\_value\_id | string | | | | oneof value. boolean\_value | bool | | | | oneof value. number\_value | int64 | | | | enum\_value\_details | [ResourceAttributeEnumValue](#resourceattributeenumvalue) | | Populated in responses with full enum value details. | | created\_date | google.protobuf.Timestamp | | The timestamp when the relation between the Entity and ResourceAttribute Key and Value was created. | | created\_by\_user\_id | string | | | | archived\_date | google.protobuf.Timestamp | | | | is\_archived | bool | | Whether or not the resource attribute is archived. This is inferred from whether archived\_date is set. | ### ResourceAttributeEntityIdentifier Represents an entity to which a resource\_attribute will be assigned. | Field | Type | Label | Description | | :----------- | :---------------------------------------------------------- | :---- | :---------- | | entity\_id | string | | | | entity\_type | [ResourceAttributeEntityType](#resourceattributeentitytype) | | | ### ResourceAttributeEnumValue Represents a possible enumerable value for ENUM type resource\_attribute keys. Users can add new enum values as needed. | Field | Type | Label | Description | | :----------------------------------- | :------------------------ | :---- | :---------------------------------------------------------------------------------------------- | | resource\_attribute\_enum\_value\_id | string | | | | resource\_attribute\_key\_id | string | | | | display\_name | string | | | | description | string | | | | created\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_date | google.protobuf.Timestamp | | | | modified\_by\_user\_id | string | | | | archived\_date | google.protobuf.Timestamp | | | | is\_archived | bool | | Whether or not the enum value is archived. This is inferred from whether archived\_date is set. | ### ResourceAttributeEnumValueIdList | Field | Type | Label | Description | | :---- | :----- | :------- | :---------- | | ids | string | repeated | | ### ResourceAttributeKey A ResourceAttribute Key defines an attribute that can be assigned to Entities for the purpose of attribute based access control (ABAC). | Field | Type | Label | Description | | :--------------------------- | :---------------------------------------------------- | :---- | :--------------------------------------------------------------------------------------- | | resource\_attribute\_key\_id | string | | | | organization\_id | string | | | | display\_name | string | | | | description | string | | | | type | [ResourceAttributeKeyType](#resourceattributekeytype) | | | | created\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_date | google.protobuf.Timestamp | | | | modified\_by\_user\_id | string | | | | archived\_date | google.protobuf.Timestamp | | | | is\_archived | bool | | Whether or not the key is archived. This is inferred from whether archived\_date is set. | ### UnarchiveResourceAttributeEnumValueRequest | Field | Type | Label | Description | | :----------------------------------- | :----- | :---- | :---------- | | resource\_attribute\_enum\_value\_id | string | | | ### UnarchiveResourceAttributeEnumValueResponse *This message has no fields.* ### UnarchiveResourceAttributeKeyRequest | Field | Type | Label | Description | | :--------------------------- | :----- | :---- | :---------- | | resource\_attribute\_key\_id | string | | | ### UnarchiveResourceAttributeKeyResponse *This message has no fields.* ### UnarchiveResourceAttributeRequest | Field | Type | Label | Description | | :---------------------- | :----- | :---- | :---------- | | resource\_attribute\_id | string | | | ### UnarchiveResourceAttributeResponse *This message has no fields.* ### UpdateResourceAttributeEnumValueRequest | Field | Type | Label | Description | | :----------------------------------- | :------------------------------------------------------ | :---- | :---------------------------------------------------------------------------------------------------------- | | resource\_attribute\_enum\_value\_id | string | | | | display\_name | string | | | | description | string | | | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The list of fields to be updated. The fields available to be updated are `description` and `archived_date`. | ### UpdateResourceAttributeEnumValueResponse | Field | Type | Label | Description | | :------------------------------- | :-------------------------------------------------------- | :---- | :---------- | | resource\_attribute\_enum\_value | [ResourceAttributeEnumValue](#resourceattributeenumvalue) | | | ### UpdateResourceAttributeKeyRequest | Field | Type | Label | Description | | :--------------------------- | :------------------------------------------------------ | :---- | :---------------------------------------------------------------------------------------------------------- | | resource\_attribute\_key\_id | string | | | | display\_name | string | | | | description | string | | | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The list of fields to be updated. The fields available to be updated are `description` and `archived_date`. | ### UpdateResourceAttributeKeyResponse | Field | Type | Label | Description | | :----------------------- | :-------------------------------------------- | :---- | :---------- | | resource\_attribute\_key | [ResourceAttributeKey](#resourceattributekey) | | | ## Enums *Allowed constant values used in message fields.* ### ResourceAttributeEntityType | Name | Number | Description | | :--------------------------------------------- | :----- | :---------- | | RESOURCE\_ATTRIBUTE\_ENTITY\_TYPE\_UNSPECIFIED | 0 | | | RESOURCE\_ATTRIBUTE\_ENTITY\_TYPE\_ASSET | 1 | | | RESOURCE\_ATTRIBUTE\_ENTITY\_TYPE\_CHANNEL | 2 | | | RESOURCE\_ATTRIBUTE\_ENTITY\_TYPE\_RUN | 3 | | ### ResourceAttributeKeyType Values become selectable enumerable options. | Name | Number | Description | | :-------------------------------------------- | :----- | :---------- | | RESOURCE\_ATTRIBUTE\_KEY\_TYPE\_UNSPECIFIED | 0 | | | RESOURCE\_ATTRIBUTE\_KEY\_TYPE\_ENUM | 1 | | | RESOURCE\_ATTRIBUTE\_KEY\_TYPE\_BOOLEAN | 2 | | | RESOURCE\_ATTRIBUTE\_KEY\_TYPE\_NUMBER | 3 | | | RESOURCE\_ATTRIBUTE\_KEY\_TYPE\_SET\_OF\_ENUM | 4 | | # resource_identifier Source: https://docs.siftstack.com/api/reference/protocol-buffers/resource_identifier sift/common/type/v1/resource_identifier.proto ## Services *RPC methods exposed by this API.* ## Messages *Data models used across requests/responses.* ### ClientKeys | Field | Type | Label | Description | | :----------- | :----- | :------- | :---------- | | client\_keys | string | repeated | | ### Ids | Field | Type | Label | Description | | :---- | :----- | :------- | :---------- | | ids | string | repeated | | ### NamedResource | Field | Type | Label | Description | | :------------------- | :----- | :---- | :---------- | | oneof resource. id | string | | | | oneof resource. name | string | | | ### NamedResources | Field | Type | Label | Description | | :--------------------- | :-------------- | :---- | :---------- | | oneof resources. ids | [Ids](#ids) | | | | oneof resources. names | [Names](#names) | | | ### Names | Field | Type | Label | Description | | :---- | :----- | :------- | :---------- | | names | string | repeated | | ### ResourceIdentifier | Field | Type | Label | Description | | :---------------------------- | :----- | :---- | :---------- | | oneof identifier. id | string | | | | oneof identifier. client\_key | string | | | ### ResourceIdentifiers | Field | Type | Label | Description | | :------------------------------ | :------------------------ | :---- | :---------- | | oneof identifiers. ids | [Ids](#ids) | | | | oneof identifiers. client\_keys | [ClientKeys](#clientkeys) | | | ## Enums *Allowed constant values used in message fields.* # resource_ref Source: https://docs.siftstack.com/api/reference/protocol-buffers/resource_ref sift/common/type/v1/resource_ref.proto ## Services *RPC methods exposed by this API.* ## Messages *Data models used across requests/responses.* ### FindResourceBy | Field | Type | Label | Description | | :---------------------------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------- | | oneof identifier. id | string | | Find by the resource's global id, e.g. asset\_id, run\_id, report\_id. | | oneof identifier. client\_key | string | | Find by the resource's client\_key, if available. | | oneof identifier. name | string | | Find by the resource's name. If multiple resources are found with the same name, an error will be returned. | | organization\_id | string | | When finding by `client_key` or `name`, the `organization_id` should also be specified. Only required if the user belongs to more than one organization. | ### ResourceRef ResourceRef is meant to be embedded as a field in other resources. It's used by one resource to point to another resource. In a request, use the `find_by` field to select a resource to point to. In a response, the fields marked `google.api.field_behavior = OUTPUT_ONLY` will be populated by the backend. | Field | Type | Label | Description | | :---------- | :-------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | id | string | | The global unique id of the resource, e.g. the asset\_id, run\_id, or report\_id. | | client\_key | string | optional | If a resource has a client\_key associated with it, it will be included. | | name | string | | The name of the resource. | | find\_by | [FindResourceBy](#findresourceby) | | Use this field to 'construct' a ResourceRef. You can give just the name, id, or client\_key and the backend will find the resource you're referring to. | ## Enums *Allowed constant values used in message fields.* # resource_type Source: https://docs.siftstack.com/api/reference/protocol-buffers/resource_type sift/common/v1/resource_type.proto ## Services *RPC methods exposed by this API.* ## Messages *Data models used across requests/responses.* ## Enums *Allowed constant values used in message fields.* ### ResourceType ResourceType represents the type of resource being accessed. | Name | Number | Description | | :-------------------------------------- | :----- | :------------------------------------------------------------------------- | | RESOURCE\_TYPE\_UNSPECIFIED | 0 | | | RESOURCE\_TYPE\_ASSET | 1 | | | RESOURCE\_TYPE\_CHANNEL | 2 | | | RESOURCE\_TYPE\_RUN | 3 | | | RESOURCE\_TYPE\_ANNOTATION | 4 | | | RESOURCE\_TYPE\_CAMPAIGN | 5 | | | RESOURCE\_TYPE\_REPORT | 6 | | | RESOURCE\_TYPE\_RULE | 7 | | | RESOURCE\_TYPE\_RULE\_VERSION | 8 | | | RESOURCE\_TYPE\_USER\_DEFINED\_FUNCTION | 9 | | | RESOURCE\_TYPE\_CALCULATED\_CHANNEL | 10 | | | RESOURCE\_TYPE\_REPORT\_TEMPLATE | 11 | | | RESOURCE\_TYPE\_TEST\_REPORT | 12 | | | RESOURCE\_TYPE\_SIFT\_APP | 1000 | Special type for a resource that doesn't yet exist (eg. creating an asset) | # roles Source: https://docs.siftstack.com/api/reference/protocol-buffers/roles sift/roles/v2/roles.proto ## Services *RPC methods exposed by this API.* ### RoleService | Method | Request | Response | Description | | :-------- | :------------------------------------ | :-------------------------------------- | :---------- | | ListRoles | [ListRolesRequest](#listrolesrequest) | [ListRolesResponse](#listrolesresponse) | | ## Messages *Data models used across requests/responses.* ### ListRolesRequest | Field | Type | Label | Description | | :---------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | page\_size | uint32 | | The maximum number of roles to return. The service may return fewer than this value. If unspecified, at most 50 roles will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. | | page\_token | string | | A page token, received from a previous `ListRoles` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListRoles` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `role_id`, `name`, and `description`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved channels. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `name` and `description`. If left empty, items are ordered by `name` in ascending order (oldest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "name desc,description" | ### ListRolesResponse | Field | Type | Label | Description | | :---------------- | :------------ | :------- | :---------- | | roles | [Role](#role) | repeated | | | next\_page\_token | string | | | ### Role | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------- | | role\_id | string | | | | name | string | | | | description | string | | | | role\_order | int32 | | | ## Enums *Allowed constant values used in message fields.* # rule_evaluation Source: https://docs.siftstack.com/api/reference/protocol-buffers/rule_evaluation sift/rule_evaluation/v1/rule_evaluation.proto ## Services *RPC methods exposed by this API.* ### RuleEvaluationService | Method | Request | Response | Description | | :------------------- | :---------------------------------------------------------- | :------------------------------------------------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------- | | EvaluateRules | [EvaluateRulesRequest](#evaluaterulesrequest) | [EvaluateRulesResponse](#evaluaterulesresponse) | Evaluate rules from a designated source against a run or asset and return the total amount of annotations created and the ID of the generated report. | | EvaluateRulesPreview | [EvaluateRulesPreviewRequest](#evaluaterulespreviewrequest) | [EvaluateRulesPreviewResponse](#evaluaterulespreviewresponse) | Perform a dry run evaluation for existing rules or rule configurations against a run and return the annotations that would be generated. | ## Messages *Data models used across requests/responses.* ### AssetsTimeRange | Field | Type | Label | Description | | :---------- | :------------------------------------------------------------------------ | :---- | :---------- | | assets | [sift.common.type.v1.NamedResources](#sift-common-type-v1-namedresources) | | | | start\_time | google.protobuf.Timestamp | | | | end\_time | google.protobuf.Timestamp | | | ### EvaluateRulesAnnotationOptions | Field | Type | Label | Description | | :---- | :------------------------------------------------------------------------ | :---- | :---------- | | tags | [sift.common.type.v1.NamedResources](#sift-common-type-v1-namedresources) | | | ### EvaluateRulesFromCurrentRuleVersions | Field | Type | Label | Description | | :---- | :---------------------------------------------------------------------------------- | :---- | :---------- | | rules | [sift.common.type.v1.ResourceIdentifiers](#sift-common-type-v1-resourceidentifiers) | | | ### EvaluateRulesFromReportTemplate | Field | Type | Label | Description | | :--------------- | :-------------------------------------------------------------------------------- | :---- | :---------- | | report\_template | [sift.common.type.v1.ResourceIdentifier](#sift-common-type-v1-resourceidentifier) | | | ### EvaluateRulesFromRuleConfigs | Field | Type | Label | Description | | :------ | :------------------------------------------------------------------ | :------- | :---------- | | configs | [sift.rules.v1.UpdateRuleRequest](#sift-rules-v1-updaterulerequest) | repeated | | ### EvaluateRulesFromRuleVersions | Field | Type | Label | Description | | :----------------- | :----- | :------- | :---------- | | rule\_version\_ids | string | repeated | | ### EvaluateRulesPreviewRequest | Field | Type | Label | Description | | :------------------------------ | :-------------------------------------------------------------------------------- | :------- | :--------------------------------------------------------------------------------------------------------------------------- | | oneof time. run | [sift.common.type.v1.ResourceIdentifier](#sift-common-type-v1-resourceidentifier) | | | | oneof time. run\_time\_range | [RunTimeRange](#runtimerange) | | | | oneof mode. rules | [EvaluateRulesFromCurrentRuleVersions](#evaluaterulesfromcurrentruleversions) | | | | oneof mode. rule\_versions | [EvaluateRulesFromRuleVersions](#evaluaterulesfromruleversions) | | | | oneof mode. report\_template | [EvaluateRulesFromReportTemplate](#evaluaterulesfromreporttemplate) | | | | oneof mode. rule\_configs | [EvaluateRulesFromRuleConfigs](#evaluaterulesfromruleconfigs) | | | | organization\_id | string | | Only required if your user belongs to multiple organizations | | run\_family\_alignment\_configs | [RunFamilyAlignmentConfig](#runfamilyalignmentconfig) | repeated | If evaluating a run against a family stat, this field will be used to provide alignment configuration for the run under test | ### EvaluateRulesPreviewResponse | Field | Type | Label | Description | | :------------------------- | :---------------------------------------------------------------- | :------- | :---------- | | created\_annotation\_count | int32 | | | | dry\_run\_annotations | [sift.rules.v1.DryRunAnnotation](#sift-rules-v1-dryrunannotation) | repeated | | ### EvaluateRulesRequest | Field | Type | Label | Description | | :--------------------------------- | :-------------------------------------------------------------------------------- | :------- | :--------------------------------------------------------------------------------------------------------------------------- | | oneof time. run | [sift.common.type.v1.ResourceIdentifier](#sift-common-type-v1-resourceidentifier) | | | | oneof time. assets | [AssetsTimeRange](#assetstimerange) | | | | oneof time. run\_time\_range | [RunTimeRange](#runtimerange) | | | | oneof mode. rules | [EvaluateRulesFromCurrentRuleVersions](#evaluaterulesfromcurrentruleversions) | | | | oneof mode. rule\_versions | [EvaluateRulesFromRuleVersions](#evaluaterulesfromruleversions) | | | | oneof mode. report\_template | [EvaluateRulesFromReportTemplate](#evaluaterulesfromreporttemplate) | | | | oneof mode. all\_applicable\_rules | bool | | | | annotation\_options | [EvaluateRulesAnnotationOptions](#evaluaterulesannotationoptions) | | | | organization\_id | string | | Only required if your user belongs to multiple organizations | | report\_name | string | optional | If this request creates a report, this field will be used as the report name. | | run\_family\_alignment\_configs | [RunFamilyAlignmentConfig](#runfamilyalignmentconfig) | repeated | If evaluating a run against a family stat, this field will be used to provide alignment configuration for the run under test | ### EvaluateRulesResponse | Field | Type | Label | Description | | :------------------------- | :----- | :------- | :------------------------------------------------------------------------------------------ | | created\_annotation\_count | int32 | | | | report\_id | string | optional | A report will be generated if rules were evaluated against a run. | | job\_id | string | optional | This will be set if the job has an extended run time and is being processed asynchronously. | ### RunFamilyAlignmentConfig | Field | Type | Label | Description | | :---------------------------------- | :---------------------------------------------------------------------------- | :---- | :---------- | | family\_alignment\_name | string | | | | oneof alignment\_config. run | [sift.families.v1.RunAlignment](#sift-families-v1-runalignment) | | | | oneof alignment\_config. annotation | [sift.families.v1.AnnotationAlignment](#sift-families-v1-annotationalignment) | | | | oneof alignment\_config. timestamp | [sift.families.v1.TimestampAlignment](#sift-families-v1-timestampalignment) | | | ### RunTimeRange | Field | Type | Label | Description | | :---------- | :-------------------------------------------------------------------------------- | :------- | :---------- | | run | [sift.common.type.v1.ResourceIdentifier](#sift-common-type-v1-resourceidentifier) | | | | start\_time | google.protobuf.Timestamp | optional | | | end\_time | google.protobuf.Timestamp | optional | | ## Enums *Allowed constant values used in message fields.* # rules Source: https://docs.siftstack.com/api/reference/protocol-buffers/rules sift/rules/v1/rules.proto ## Services *RPC methods exposed by this API.* ### RuleService | Method | Request | Response | Description | | :----------------------- | :------------------------------------------------------------------ | :-------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | SearchRules | [SearchRulesRequest](#searchrulesrequest) | [SearchRulesResponse](#searchrulesresponse) | Queries rules based on provided search parameters. | | GetRule | [GetRuleRequest](#getrulerequest) | [GetRuleResponse](#getruleresponse) | Retrieves the latest version of a rule. | | BatchGetRules | [BatchGetRulesRequest](#batchgetrulesrequest) | [BatchGetRulesResponse](#batchgetrulesresponse) | Retrieve multiple rules. | | CreateRule | [CreateRuleRequest](#createrulerequest) | [CreateRuleResponse](#createruleresponse) | Creates a rule. | | UpdateRule | [UpdateRuleRequest](#updaterulerequest) | [UpdateRuleResponse](#updateruleresponse) | Updates an existing rule. | | BatchUpdateRules | [BatchUpdateRulesRequest](#batchupdaterulesrequest) | [BatchUpdateRulesResponse](#batchupdaterulesresponse) | Updates existing rules or creates rules that do not exist. | | DeleteRule | [DeleteRuleRequest](#deleterulerequest) | [DeleteRuleResponse](#deleteruleresponse) | **Deprecated.** Deprecated - use ArchiveRule instead. Archives a rule. | | ArchiveRule | [ArchiveRuleRequest](#archiverulerequest) | [ArchiveRuleResponse](#archiveruleresponse) | Archives a rule. | | BatchDeleteRules | [BatchDeleteRulesRequest](#batchdeleterulesrequest) | [BatchDeleteRulesResponse](#batchdeleterulesresponse) | **Deprecated.** Deprecated - use BatchArchiveRules instead. Archives multiple rules. | | BatchArchiveRules | [BatchArchiveRulesRequest](#batcharchiverulesrequest) | [BatchArchiveRulesResponse](#batcharchiverulesresponse) | Batch archives rules. | | UnarchiveRule | [UnarchiveRuleRequest](#unarchiverulerequest) | [UnarchiveRuleResponse](#unarchiveruleresponse) | Unarchives a rule. | | BatchUnarchiveRules | [BatchUnarchiveRulesRequest](#batchunarchiverulesrequest) | [BatchUnarchiveRulesResponse](#batchunarchiverulesresponse) | Batch unarchives rules. | | UndeleteRule | [UndeleteRuleRequest](#undeleterulerequest) | [UndeleteRuleResponse](#undeleteruleresponse) | **Deprecated.** Deprecated - use UnarchiveRule instead. Unarchives a rule | | BatchUndeleteRules | [BatchUndeleteRulesRequest](#batchundeleterulesrequest) | [BatchUndeleteRulesResponse](#batchundeleterulesresponse) | **Deprecated.** Deprecated - use BatchUnarchiveRules instead. Unarchives multiple rules | | EvaluateRules | [EvaluateRulesRequest](#evaluaterulesrequest) | [EvaluateRulesResponse](#evaluaterulesresponse) | **Deprecated.** Deprecated - use RuleEvaluationService instead. | | ViewHumanFriendlyRules | [ViewHumanFriendlyRulesRequest](#viewhumanfriendlyrulesrequest) | [ViewHumanFriendlyRulesResponse](#viewhumanfriendlyrulesresponse) | **Deprecated.** Deprecated - use ViewJsonRules instead. Retrieve a JSON object containing all of the rules for a given asset. | | ViewJsonRules | [ViewJsonRulesRequest](#viewjsonrulesrequest) | [ViewJsonRulesResponse](#viewjsonrulesresponse) | **Deprecated.** Deprecated - use BatchGetRules instead. Retrieve a JSON object containing all of the rules for a given asset. | | UpdateHumanFriendlyRules | [UpdateHumanFriendlyRulesRequest](#updatehumanfriendlyrulesrequest) | [UpdateHumanFriendlyRulesResponse](#updatehumanfriendlyrulesresponse) | **Deprecated.** Deprecated - use BatchUpdateRules instead. Batch update rules given the `rules_json` which is a JSON list of rules. | | ValidateJsonRules | [ValidateJsonRulesRequest](#validatejsonrulesrequest) | [ValidateJsonRulesResponse](#validatejsonrulesresponse) | **Deprecated.** Deprecated - use BatchUpdateRules with validate\_only flag instead. Validate a batch update for rules given the `rules_json` which is a JSON list of rules. This is a dry-run operation. | | UpdateJsonRules | [UpdateJsonRulesRequest](#updatejsonrulesrequest) | [UpdateJsonRulesResponse](#updatejsonrulesresponse) | **Deprecated.** Deprecated - use BatchUpdateRules instead. Batch update rules given the `rules_json` which is a JSON list of rules. | | ListRules | [ListRulesRequest](#listrulesrequest) | [ListRulesResponse](#listrulesresponse) | | | ListRuleVersions | [ListRuleVersionsRequest](#listruleversionsrequest) | [ListRuleVersionsResponse](#listruleversionsresponse) | Retrieves a list of rule versions for the given rule. | | GetRuleVersion | [GetRuleVersionRequest](#getruleversionrequest) | [GetRuleVersionResponse](#getruleversionresponse) | Retrieves a specific version of a rule. | | BatchGetRuleVersions | [BatchGetRuleVersionsRequest](#batchgetruleversionsrequest) | [BatchGetRuleVersionsResponse](#batchgetruleversionsresponse) | Retrieves multiple rules by rule versions. | ## Messages *Data models used across requests/responses.* ### AnnotationActionConfiguration | Field | Type | Label | Description | | :--------------------- | :------------------------------------------------------------------------ | :------- | :---------- | | tag\_ids | string | repeated | | | annotation\_type | [sift.annotations.v1.AnnotationType](#sift-annotations-v1-annotationtype) | | | | assigned\_to\_user\_id | string | optional | | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | | ### ArchiveRuleRequest ArchiveRuleRequest is used to archive a rule by rule\_id or client\_key. If both are provided, only rule\_id will be used. | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------- | | rule\_id | string | | | | client\_key | string | | | ### ArchiveRuleResponse *This message has no fields.* ### AssetExpressionValidationResult | Field | Type | Label | Description | | :------------- | :----- | :------- | :------------------------------------------------------------------------------ | | asset\_id | string | | | | asset\_name | string | | | | asset\_tag\_id | string | | asset\_tag\_id is the tag\_id that caused this asset to be included in the rule | | error | string | optional | | ### BatchArchiveRulesRequest BatchArchiveRulesRequest is used to archive a rule by rule\_id or client\_key. For each rule if both are provided, only rule\_id will be used. | Field | Type | Label | Description | | :----------- | :----- | :------- | :---------- | | rule\_ids | string | repeated | | | client\_keys | string | repeated | | ### BatchArchiveRulesResponse *This message has no fields.* ### BatchDeleteRulesRequest BatchDeleteRulesRequest is used to delete a rule by rule\_id or client\_key. For each rule if both are provided, only rule\_id will be used. | Field | Type | Label | Description | | :----------- | :----- | :------- | :---------- | | rule\_ids | string | repeated | | | client\_keys | string | repeated | | ### BatchDeleteRulesResponse *This message has no fields.* ### BatchGetRuleVersionsRequest | Field | Type | Label | Description | | :----------------- | :----- | :------- | :---------- | | rule\_version\_ids | string | repeated | | ### BatchGetRuleVersionsResponse | Field | Type | Label | Description | | :---- | :------------ | :------- | :---------- | | rules | [Rule](#rule) | repeated | | ### BatchGetRulesRequest BatchGetRulesRequest is used to retrieve rules by rule\_ids or client\_keys. If both are provided, both will be used to retrieve rules. | Field | Type | Label | Description | | :----------- | :----- | :------- | :---------- | | rule\_ids | string | repeated | | | client\_keys | string | repeated | | ### BatchGetRulesResponse | Field | Type | Label | Description | | :---- | :------------ | :------- | :---------- | | rules | [Rule](#rule) | repeated | | ### BatchUnarchiveRulesRequest BatchUnarchiveRulesRequest is used to unarchive a rule by rule\_id or client\_key. For each rule if both are provided, only rule\_id will be used. | Field | Type | Label | Description | | :----------- | :----- | :------- | :---------- | | rule\_ids | string | repeated | | | client\_keys | string | repeated | | ### BatchUnarchiveRulesResponse *This message has no fields.* ### BatchUndeleteRulesRequest BatchUndeleteRulesRequest is used to delete a rule by rule\_id or client\_key. For each rule if both are provided, only rule\_id will be used. | Field | Type | Label | Description | | :----------- | :----- | :------- | :---------- | | rule\_ids | string | repeated | | | client\_keys | string | repeated | | ### BatchUndeleteRulesResponse *This message has no fields.* ### BatchUpdateRulesRequest | Field | Type | Label | Description | | :------------------------------- | :-------------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | rules | [UpdateRuleRequest](#updaterulerequest) | repeated | rules are limited 1000 rules at a time | | validate\_only | bool | | If validate\_only is true, the request will only validate the request and not save the rules. | | override\_expression\_validation | bool | | **Deprecated.** Discouraged escape hatch for saving rules whose expression cannot be fully validated server-side. When `true`: - Per-asset expression validation errors (e.g. channel not present on the in-scope asset) are returned in `validation_results` for visibility but do not block the save. - If the rule's UDF/calculated-channel inlining cannot resolve types (typically because the referenced channels haven't been ingested yet, or there are too many distinct identifiers for the type-inference budget) the rule is still persisted, but its `is_live_evaluation_enabled` is forced to `false`. Live alerts will skip it; report generation and on-demand `EvaluateRules` calls still work because they re-resolve types at run time. To bring such a rule back online, fix the underlying problem (ingest the channels, simplify the expression, etc.) and reissue an update with `is_live_evaluation_enabled = true`. | Marked `deprecated = true` because new integrations should validate input *before* submitting; existing SDK call sites that rely on this flag continue to work. | ### BatchUpdateRulesResponse | Field | Type | Label | Description | | :------------------------- | :------------------------------------------------------------------------------------ | :------- | :-------------------------------------------------------------------------------------------------------------------------------------- | | success | bool | | | | rules\_created\_count | int32 | | The total number of rules created in the request. If validate\_only is true, this will indicate how many rules would have been created. | | rules\_updated\_count | int32 | | The total number of rules updated in the request. If validate\_only is true, this will indicate how many rules would have been updated. | | validate\_only | bool | | This will be true if the request only validated the request and did not save the rules. | | validation\_results | [ValidationResult](#validationresult) | repeated | One ValidationResult per rule in the request will be returned | | created\_rule\_identifiers | [BatchUpdateRulesResponse.RuleIdentifiers](#batchupdaterulesresponse-ruleidentifiers) | repeated | The created rule id, name, version, and client key. | ### BatchUpdateRulesResponse.RuleIdentifiers | Field | Type | Label | Description | | :---------- | :----- | :------- | :---------- | | rule\_id | string | | | | name | string | | | | client\_key | string | optional | | ### CalculatedChannelConfig | Field | Type | Label | Description | | :-------------------------------- | :-------------------------------------------------------------------------------------------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------------- | | channel\_references | [CalculatedChannelConfig.ChannelReferencesEntry](#calculatedchannelconfig-channelreferencesentry) | repeated | | | expression | string | | | | function\_dependencies | [sift.common.type.v1.FunctionDependency](#sift-common-type-v1-functiondependency) | repeated | This will be ignored in requests and will be generated automatically. | | calculated\_channel\_dependencies | [sift.common.type.v1.CalculatedChannelDependency](#sift-common-type-v1-calculatedchanneldependency) | repeated | This will be ignored in requests and will be generated automatically. Tracks which calculated channel versions this rule depends on. | ### CalculatedChannelConfig.ChannelReferencesEntry | Field | Type | Label | Description | | :---- | :------------------------------------ | :---- | :---------- | | key | string | | | | value | [ChannelReference](#channelreference) | | | ### ChannelReference | Field | Type | Label | Description | | :------------------------------- | :----- | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | name | string | | Required for native channel references. Must not be set when calculated\_channel\_version\_id is provided. | | component | string | | Deprecated - use name instead. If provided, name will be joined with the component as `component.name`. Must not be set when calculated\_channel\_version\_id is provided. | | calculated\_channel\_version\_id | string | optional | Reference to a calculated channel version. When set, the rule will use the calculated channel instead of looking up a native channel by name. Must not be set when name is provided. | ### ContextualChannels | Field | Type | Label | Description | | :------- | :------------------------------------ | :------- | :---------- | | channels | [ChannelReference](#channelreference) | repeated | | ### CreateRuleRequest | Field | Type | Label | Description | | :----- | :-------------------------------------- | :---- | :---------- | | update | [UpdateRuleRequest](#updaterulerequest) | | | ### CreateRuleResponse | Field | Type | Label | Description | | :------- | :----- | :---- | :---------- | | rule\_id | string | | | ### DeleteRuleRequest DeleteRuleRequest is used to delete a rule by rule\_id or client\_key. If both are provided, only rule\_id will be used. | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------- | | rule\_id | string | | | | client\_key | string | | | ### DeleteRuleResponse *This message has no fields.* ### DryRunAnnotation | Field | Type | Label | Description | | :--------------------- | :------------------------ | :---- | :---------- | | condition\_id | string | | | | name | string | | | | start\_time | google.protobuf.Timestamp | | | | end\_time | google.protobuf.Timestamp | | | | condition\_version\_id | string | | | ### EvaluateRulesRequest Deprecated - use RuleEvaluationService instead. | Field | Type | Label | Description | | :---------------------- | :-------------------------------------------------------- | :------- | :---------- | | rule\_ids | string | repeated | | | annotation\_options | [EvaluatedAnnotationOptions](#evaluatedannotationoptions) | | | | oneof time. run\_id | string | | | | oneof time. time\_range | [TimeRangeQuery](#timerangequery) | | | | dry\_run | bool | | | ### EvaluateRulesResponse Deprecated - use RuleEvaluationService instead. | Field | Type | Label | Description | | :------------------------- | :------------------------------------ | :------- | :------------------------------------------------------------------------------------------------------------ | | created\_annotation\_count | int32 | | | | dry\_run\_annotations | [DryRunAnnotation](#dryrunannotation) | repeated | If dry\_run is true, this will be populated with the annotations that would be created | | job\_id | string | optional | job\_id and report\_id will be set if the job has an extended run time and is being processed asynchronously. | | report\_id | string | optional | | ### EvaluatedAnnotationOptions | Field | Type | Label | Description | | :------- | :----- | :------- | :---------- | | tag\_ids | string | repeated | | ### FamilyStatReference | Field | Type | Label | Description | | :------------------------ | :----- | :---- | :--------------------------------------------------------------------------------------------------- | | reference | string | | How to refer to the family stat in the expression, e.g. \$A | | family\_id | string | | Choose the family, e.g. Sift Rocket Engine | | family\_stat\_name | string | | Choose the stat, e.g. TC-TURB.avg | | family\_stat\_expression | string | | | | family\_stat\_range\_name | string | | Choose the range by name, which will be used to resolve the alignment and range, e.g. Startup +/- 5s | ### GetRuleRequest GetRuleRequest is used to retrieve a rule by rule\_id or client\_key. If both are provided, only rule\_id will be used. | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------- | | rule\_id | string | | | | client\_key | string | | | ### GetRuleResponse | Field | Type | Label | Description | | :---- | :------------ | :---- | :---------- | | rule | [Rule](#rule) | | | ### GetRuleVersionRequest | Field | Type | Label | Description | | :---------------- | :----- | :---- | :---------- | | rule\_version\_id | string | | | ### GetRuleVersionResponse | Field | Type | Label | Description | | :---- | :------------ | :---- | :---------- | | rule | [Rule](#rule) | | | ### JsonRulesRequest | Field | Type | Label | Description | | :--------------- | :----- | :---- | :---------- | | asset\_id | string | | | | rules\_json | string | | | | organization\_id | string | | | ### JsonRulesResponse | Field | Type | Label | Description | | :-------------------- | :----- | :------- | :---------- | | success | bool | | | | total\_rules\_count | int32 | | | | rules\_created\_count | int32 | | | | rules\_updated\_count | int32 | | | | rules\_deleted\_count | int32 | | | | error\_messages | string | optional | | ### LastValueThreshold *This message has no fields.* ### ListRuleVersionsRequest | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | rule\_id | string | | | | page\_size | uint32 | | The maximum number of Rule Versions to return. The service may return fewer than this value. If unspecified, at most 50 Rule Versions will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. | | page\_token | string | | A page token, received from a previous `ListRuleVersions` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListRuleVersions` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `rule_version_id`, `user_notes`, and `change_message`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). Optional. | ### ListRuleVersionsResponse | Field | Type | Label | Description | | :---------------- | :-------------------------- | :------- | :---------- | | rule\_versions | [RuleVersion](#ruleversion) | repeated | | | next\_page\_token | string | | | ### ListRulesRequest | Field | Type | Label | Description | | :---------- | :----- | :---- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of Rules to return. The service may return fewer than this value. If unspecified, at most 50 Rules will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. | | page\_token | string | | A page token, received from a previous `ListRules` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListRules` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `rule_id`, `client_key`, `name`, `description`, `is_external`, `asset_id`, `tag_id`, `created_date`, `created_by_user_id`, `metadata`, `modified_date`, `modified_by_user_id`, `deleted_date`, `is_archived`, `archived_date`, and `is_live_evaluation_enabled`. Metadata can be used in filters by using `metadata.{metadata_key_name}` as the field name. Folder membership is filterable via the `folders` and `activeFolders` fields. Both contain the ids of the folders the rule belongs to; `activeFolders` excludes archived folders. Use `"" in folders` to return rules in the given folder, and `size(activeFolders) == 0` to return uncategorized rules (rules whose only memberships are in archived folders count as uncategorized). For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). Optional. | | order\_by | string | | How to order the retrieved Rules. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date` and `modified_date`. If left empty, items are ordered by `created_date` in descending order (newest-first). | ### ListRulesResponse | Field | Type | Label | Description | | :---------------- | :------------ | :------- | :---------- | | rules | [Rule](#rule) | repeated | | | next\_page\_token | string | | | ### NotificationActionConfiguration | Field | Type | Label | Description | | :------------------- | :----- | :------- | :---------- | | recipient\_user\_ids | string | repeated | | ### Rule | Field | Type | Label | Description | | :---------------------------- | :---------------------------------------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------- | | rule\_id | string | | | | asset\_id | string | | **Deprecated.** | | name | string | | | | description | string | | | | is\_enabled | bool | | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | organization\_id | string | | | | conditions | [RuleCondition](#rulecondition) | repeated | | | rule\_version | [RuleVersion](#ruleversion) | | | | client\_key | string | | client\_key is a client provided identifier for the rule. It is immutable after rule creation. | | asset\_configuration | [RuleAssetConfiguration](#ruleassetconfiguration) | | | | contextual\_channels | [ContextualChannels](#contextualchannels) | | | | deleted\_date | google.protobuf.Timestamp | | **Deprecated.** | | is\_external | bool | | | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | | | archived\_date | google.protobuf.Timestamp | | archived\_date indicates when the rule was archived | | is\_archived | bool | | is\_archived is inferred from when archived\_date is not null | | is\_live\_evaluation\_enabled | bool | | If `true`, this rule will be evaluated on live data; if `false`, live rule evaluation is disabled (the rule remains usable for report generation). | Note: this value is the server's effective state, not necessarily what was requested. A rule saved via `BatchUpdateRulesRequest.override_expression_validation = true` whose UDF inlining fails (e.g. type resolution exhausted; see error returned by `BatchUpdateRules`) is forced to `is_live_evaluation_enabled = false` even when the caller requested `true`. To recover after the underlying issue is fixed (channels populated, expression simplified, etc.), reissue an `UpdateRule` / `BatchUpdateRules` request that explicitly sets `is_live_evaluation_enabled = true`. | \| current\_version\_id | string | | The current version of the rule. This is may be different from the rule\_version.version if the rule has been updated since the rule\_version was created. | \| folder\_ids | string | repeated | Ids of the folders this rule belongs to. | ### RuleAction | Field | Type | Label | Description | | :------------------------ | :-------------------------------------------------- | :---- | :---------- | | rule\_action\_id | string | | | | rule\_condition\_id | string | | | | action\_type | [ActionKind](#actionkind) | | | | configuration | [RuleActionConfiguration](#ruleactionconfiguration) | | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | rule\_action\_version\_id | string | | | ### RuleActionConfiguration | Field | Type | Label | Description | | :-------------------------------- | :------------------------------------------------------------------ | :---- | :---------- | | oneof configuration. notification | [NotificationActionConfiguration](#notificationactionconfiguration) | | | | oneof configuration. annotation | [AnnotationActionConfiguration](#annotationactionconfiguration) | | | | oneof configuration. webhook | [WebhookActionConfiguration](#webhookactionconfiguration) | | | ### RuleAssetConfiguration | Field | Type | Label | Description | | :--------- | :----- | :------- | :---------- | | asset\_ids | string | repeated | | | tag\_ids | string | repeated | | ### RuleCondition | Field | Type | Label | Description | | :--------------------------- | :-------------------------------------------------- | :------- | :---------- | | rule\_condition\_id | string | | | | rule\_id | string | | | | expression | [RuleConditionExpression](#ruleconditionexpression) | | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | actions | [RuleAction](#ruleaction) | repeated | | | rule\_condition\_version\_id | string | | | ### RuleConditionExpression | Field | Type | Label | Description | | :-------------------------------------------- | :---------------------------------------------------------------------- | :---- | :-------------- | | oneof expression. single\_channel\_comparison | [SingleChannelComparisonExpression](#singlechannelcomparisonexpression) | | **Deprecated.** | | oneof expression. calculated\_channel | [CalculatedChannelConfig](#calculatedchannelconfig) | | | ### RuleVersion | Field | Type | Label | Description | | :------------------------- | :------------------------ | :---- | :------------------------------------------------------------ | | rule\_id | string | | | | rule\_version\_id | string | | | | version | string | | | | created\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | version\_notes | string | | | | generated\_change\_message | string | | | | deleted\_date | google.protobuf.Timestamp | | **Deprecated.** | | archived\_date | google.protobuf.Timestamp | | archived\_date indicates when the rule version was archived | | is\_archived | bool | | is\_archived is inferred from when archived\_date is not null | ### SearchRulesRequest | Field | Type | Label | Description | | :--------------- | :------------------------------------------------------------------------ | :------- | :---------------------------------------------------------------- | | limit | uint32 | optional | Max number of rules to return (returns all if omitted). | | offset | uint32 | | Only applies if limit provided. | | order | [SearchOrder](#searchorder) | optional | Order to sort results by (defaults to ascending). | | name\_matches | string | | | | case\_sensitive | bool | | | | regexp | bool | | | | order\_by | string | optional | | | rule\_ids | string | repeated | If provided, only returns rules with the given ids | | asset\_ids | string | repeated | If provided, only returns rules that apply to the given asset ids | | include\_deleted | bool | | | | asset\_tags | [sift.common.type.v1.NamedResources](#sift-common-type-v1-namedresources) | | If provided, returns rules with assets that have the given tags | ### SearchRulesResponse | Field | Type | Label | Description | | :---- | :------------ | :------- | :---------------------------------------------------------------------------------------------- | | count | uint32 | | | | rules | [Rule](#rule) | repeated | Conditions are not included in the search response. The latest version of the rule is returned. | ### SingleChannelComparisonExpression Deprecated - use CalculatedChannelConfig. | Field | Type | Label | Description | | :--------------------------- | :------------------------------------------ | :---- | :--------------------------------------------------------------------------------------------------------------------------------------- | | channel\_component | string | | Deprecated - use channel\_name instead. If provided, channel\_component will be joined with the name as `channel_component.channel_name` | | channel\_name | string | | | | comparator | [ConditionComparator](#conditioncomparator) | | | | oneof threshold. double | double | | | | oneof threshold. string | string | | | | oneof threshold. last\_value | [LastValueThreshold](#lastvaluethreshold) | | | ### TimeRangeQuery | Field | Type | Label | Description | | :---------- | :------------------------ | :---- | :---------- | | start\_time | google.protobuf.Timestamp | | | | end\_time | google.protobuf.Timestamp | | | ### UnarchiveRuleRequest UnarchiveRuleRequest is used to unarchive a rule by rule\_id or client\_key. If both are provided, only rule\_id will be used. | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------- | | rule\_id | string | | | | client\_key | string | | | ### UnarchiveRuleResponse *This message has no fields.* ### UndeleteRuleRequest UndeleteRuleRequest is used to undelete a rule by rule\_id or client\_key. If both are provided, only rule\_id will be used. | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------- | | rule\_id | string | | | | client\_key | string | | | ### UndeleteRuleResponse *This message has no fields.* ### UpdateActionRequest | Field | Type | Label | Description | | :--------------- | :-------------------------------------------------- | :------- | :---------- | | rule\_action\_id | string | optional | | | action\_type | [ActionKind](#actionkind) | | | | configuration | [RuleActionConfiguration](#ruleactionconfiguration) | | | ### UpdateConditionRequest | Field | Type | Label | Description | | :------------------ | :-------------------------------------------------- | :------- | :---------- | | rule\_condition\_id | string | optional | | | expression | [RuleConditionExpression](#ruleconditionexpression) | | | | actions | [UpdateActionRequest](#updateactionrequest) | repeated | | ### UpdateHumanFriendlyRulesRequest Deprecated - use UpdateJsonRulesRequest. | Field | Type | Label | Description | | :--------------- | :----- | :---- | :---------- | | asset\_id | string | | | | rules\_json | string | | | | organization\_id | string | | | ### UpdateHumanFriendlyRulesResponse Deprecated - use UpdateJsonRulesResponse. | Field | Type | Label | Description | | :----------- | :----- | :---- | :---------- | | success | bool | | | | rules\_count | int32 | | | | messages | string | | | ### UpdateJsonRulesRequest | Field | Type | Label | Description | | :------ | :------------------------------------ | :---- | :---------- | | request | [JsonRulesRequest](#jsonrulesrequest) | | | ### UpdateJsonRulesResponse | Field | Type | Label | Description | | :------- | :-------------------------------------- | :---- | :---------- | | response | [JsonRulesResponse](#jsonrulesresponse) | | | ### UpdateRuleRequest UpdateRuleRequest is used to create or update a rule. If the rule\_id or client\_key is provided, the rule will be updated. If not, a new rule will be created. | Field | Type | Label | Description | | :---------------------------- | :---------------------------------------------------------------- | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | rule\_id | string | optional | | | name | string | | | | description | string | | | | asset\_id | string | | **Deprecated.** Deprecated - use asset\_configuration instead. | | is\_enabled | bool | | **Deprecated.** Deprecated - use DeleteRule instead. | | conditions | [UpdateConditionRequest](#updateconditionrequest) | repeated | | | organization\_id | string | | | | version\_notes | string | | | | client\_key | string | optional | client\_key is a client provided identifier for the rule. It is immutable after being set | | asset\_configuration | [RuleAssetConfiguration](#ruleassetconfiguration) | | | | contextual\_channels | [ContextualChannels](#contextualchannels) | | | | is\_external | bool | | | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | | | is\_archived | bool | | | | is\_live\_evaluation\_enabled | bool | optional | If set to `true` then this rule will be evaluated on live data, otherwise live rule evaluation will be disabled. This rule can still be used, however, in report generation. If this value is null then the original value is preserved. | This is a request, not a guarantee. When combined with `BatchUpdateRulesRequest.override_expression_validation = true`, a `true` value here can be silently overridden to `false` if UDF inlining fails (the rule is still persisted, just with live evaluation disabled). Re-send this request with the underlying issue resolved -- e.g. the referenced channels populated, or the expression simplified -- to flip it back on. | ### UpdateRuleResponse | Field | Type | Label | Description | | :------- | :----- | :---- | :---------- | | rule\_id | string | | | ### ValidateJsonRulesRequest | Field | Type | Label | Description | | :------ | :------------------------------------ | :---- | :---------- | | request | [JsonRulesRequest](#jsonrulesrequest) | | | ### ValidateJsonRulesResponse | Field | Type | Label | Description | | :------- | :-------------------------------------- | :---- | :---------- | | response | [JsonRulesResponse](#jsonrulesresponse) | | | ### ValidationResult | Field | Type | Label | Description | | :------------------------------------- | :------------------------------------------------------------------ | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | rule\_id | string | | | | client\_key | string | | | | asset\_expression\_validation\_results | [AssetExpressionValidationResult](#assetexpressionvalidationresult) | repeated | If the expression is invalid for an asset, one or more AssetExpressionValidationResult will be returned. This may block saving if the override\_expression\_validation flag is not set. | | error | string | optional | If the rule is invalid and unable to be saved, this will contain the error message. Expression errors will be returned in the asset\_expression\_validation\_results. | | rule\_name | string | | | ### ViewHumanFriendlyRulesRequest Deprecated - use ViewJsonRulesRequest. | Field | Type | Label | Description | | :-------- | :----- | :---- | :---------- | | asset\_id | string | | | ### ViewHumanFriendlyRulesResponse Deprecated - use ViewJsonRulesResponse. | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------- | | rules\_json | string | | | ### ViewJsonRulesRequest | Field | Type | Label | Description | | :-------- | :----- | :---- | :---------- | | asset\_id | string | | | ### ViewJsonRulesResponse | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------- | | rules\_json | string | | | ### WebhookActionConfiguration | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------- | | webhook\_id | string | | | ## Enums *Allowed constant values used in message fields.* ### ActionKind | Name | Number | Description | | :------------------------ | :----- | :-------------- | | ACTION\_KIND\_UNSPECIFIED | 0 | **Deprecated.** | | NOTIFICATION | 1 | | | ANNOTATION | 2 | | | WEBHOOK | 3 | | ### ConditionComparator | Name | Number | Description | | :--------------------------------- | :----- | :-------------- | | CONDITION\_COMPARATOR\_UNSPECIFIED | 0 | **Deprecated.** | | LESS\_THAN | 1 | | | LESS\_THAN\_OR\_EQUAL | 2 | | | GREATER\_THAN | 3 | | | GREATER\_THAN\_OR\_EQUAL | 4 | | | EQUAL | 5 | | | NOT\_EQUAL | 6 | | ### SearchOrder | Name | Number | Description | | :------------------------- | :----- | :-------------- | | SEARCH\_ORDER\_UNSPECIFIED | 0 | **Deprecated.** | | SEARCH\_ORDER\_ASC | 1 | | | SEARCH\_ORDER\_DESC | 2 | | # runs Source: https://docs.siftstack.com/api/reference/protocol-buffers/runs sift/runs/v2/runs.proto ## Services *RPC methods exposed by this API.* ### RunService | Method | Request | Response | Description | | :------------------------------------- | :---------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GetRun | [GetRunRequest](#getrunrequest) | [GetRunResponse](#getrunresponse) | Retrieve a run. | | ListRuns | [ListRunsRequest](#listrunsrequest) | [ListRunsResponse](#listrunsresponse) | Retrieve runs using an optional filter. | | CreateRun | [CreateRunRequest](#createrunrequest) | [CreateRunResponse](#createrunresponse) | Create a run. | | CreateAdhocRun | [CreateAdhocRunRequest](#createadhocrunrequest) | [CreateAdhocRunResponse](#createadhocrunresponse) | Create adhoc run, this is used to create a run after the data has been ingested | | UpdateRun | [UpdateRunRequest](#updaterunrequest) | [UpdateRunResponse](#updaterunresponse) | Updates an existing run using using the list of fields specified in `update_mask`. | | DeleteRun | [DeleteRunRequest](#deleterunrequest) | [DeleteRunResponse](#deleterunresponse) | **Deprecated.** Permanently delete a given run. In order for a run to be deleted it must have a set `stop_time`. Deprecated: Use update with is\_archived. | | StopRun | [StopRunRequest](#stoprunrequest) | [StopRunResponse](#stoprunresponse) | Set the stop time of a run to the current time. To set the stop time of a run to an arbitrary time see `UpdateRun`. | | ValidateRunFilter | [ValidateRunFilterRequest](#validaterunfilterrequest) | [ValidateRunFilterResponse](#validaterunfilterresponse) | Validates a CEL filter expression against the available run filter fields. Returns an error message if the expression is invalid, or an empty error\_message if valid. | | CreateAutomaticRunAssociationForAssets | [CreateAutomaticRunAssociationForAssetsRequest](#createautomaticrunassociationforassetsrequest) | [CreateAutomaticRunAssociationForAssetsResponse](#createautomaticrunassociationforassetsresponse) | Associates a list of assets with a given run. | ## Messages *Data models used across requests/responses.* ### CreateAdhocRunRequest The request for a call to `RunService_CreateAdhocRun` to create an adhoc run. | Field | Type | Label | Description | | :---------- | :---------------------------------------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------- | | name | string | | The name that will be assigned to the new run. | | description | string | | A description about the new run. | | start\_time | google.protobuf.Timestamp | | The time at which data ingestion began for this new run. It must be before the `stop_time` | | stop\_time | google.protobuf.Timestamp | | The time at which data ingestion concluded for this new run. | | asset\_ids | string | repeated | A list of asset IDs to associate with the new run. | | tags | string | repeated | Tags to associate with the new run. | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | The metadata values associated with this run. | | client\_key | string | optional | An arbitrary user-chosen key that uniquely identifies this run. Optional, though it is recommended to provide. | ### CreateAdhocRunResponse The response of a call to `RunService_CreateAdhocRun` containing the newly created adhoc run. | Field | Type | Label | Description | | :---- | :---------- | :---- | :---------- | | run | [Run](#run) | | | ### CreateAutomaticRunAssociationForAssetsRequest | Field | Type | Label | Description | | :----------- | :----- | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | run\_id | string | | The ID of the run to associate the asset with. | | asset\_names | string | repeated | A list of asset names to automatically associate with the run. Any data that is received for these assets will automatically added to the run. This applies even if the run has concluded, so long as the new data contains timestamps that are between the `start_time` and `stop_time`. If any of the assets are already associated with a different run whose run period (the period between `start_time` and `end_time`) overlaps with the requested run period, an error will be returned. | ### CreateAutomaticRunAssociationForAssetsResponse *This message has no fields.* ### CreateRunRequest The request of a call to `RunService_CreateRuns` to create a new run. | Field | Type | Label | Description | | :---------------------- | :---------------------------------------------------------------- | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | name | string | | The name that will be assigned to the new run. | | description | string | | A description about the new run. | | tags | string | repeated | Tags to associate with the new run. | | start\_time | google.protobuf.Timestamp | | The time at which data ingestion begins for this new run. It must be before the `stop_time`, and it must be provided if a `stop_time` is provided. Important note: `start_time` will be automatically computed during data ingestion and will be set based on the timestamp of the data for this run. | | stop\_time | google.protobuf.Timestamp | | The time at which data ingestion for this new run concludes. Important note: `stop_time` will be automatically computed during data ingestion and will be set based on the timestamp of the data for this run. | | organization\_id | string | | An organization ID is only required if the user belongs to multiple organizations. | | client\_key | string | optional | An arbitrary user-chosen key that uniquely identifies this run. Optional, though it is recommended to provide. | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | The metadata values associated with this run. | | create\_default\_report | bool | optional | Whether to create a default report for this run. This facilitates getting the report ID for live rules that will be automatically created for this run which can streamline programatically creating Campaigns. Defaults to false if not specified (This default can be changed for your organization by Sift. Contact support to change this default behavior.). | ### CreateRunResponse | Field | Type | Label | Description | | :---- | :---------- | :---- | :---------- | | run | [Run](#run) | | | ### DeleteRunRequest The request for a call to `RunService_DeleteRun`. | Field | Type | Label | Description | | :------ | :----- | :---- | :---------- | | run\_id | string | | | ### DeleteRunResponse The response of a call to `RunService_DeleteRun`. *This message has no fields.* ### GetRunRequest The request for a call to `RunService_GetRun` to retrieve run. | Field | Type | Label | Description | | :------ | :----- | :---- | :----------------------------- | | run\_id | string | | The ID of the run to retrieve. | ### GetRunResponse The response of a call to `RunService_GetRun` containing the requested run. | Field | Type | Label | Description | | :---- | :---------- | :---- | :---------- | | run | [Run](#run) | | | ### ListRunsRequest The request for a call to `RunService_ListRuns` to retrieve runs. | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of runs to return. The service may return fewer than this value. If unspecified, at most 50 runs will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. | | page\_token | string | | A page token, received from a previous `ListRuns` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListRuns` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `run_id` `organization_id`, `asset_id`, `asset_name`, `client_key`, `name`, `description`, `created_by_user_id`, `modified_by_user_id`, `created_date`, `modified_date`, `start_time`, `stop_time`, `tag_id`, `asset_tag_id`, `duration`, 'duration\_string', `annotation_comments_count`, `annotation_state`, `archived_date`, `is_archived`, and `metadata`. Metadata can be used in filters by using `metadata.{metadata_key_name}` as the field name. `duration` is in the format of elapsed seconds and `duration_string` allows for `h`, `m`, `s`, `ms` suffixes (example: \`duration\_string > duration('10h')) For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved runs. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `name`, `description`, `created_date`, `modified_date`, `start_time`, and `stop_time`. If left empty, items are ordered by `created_date` in descending order (newest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | Results can also be ordered by the value of a single metadata key, using the same bracket syntax as `filter`: `metadata[""][ desc]`. Metadata ordering cannot be combined with other order\_by fields, and runs without the key sort last in both directions. Keys with relation-typed values cannot be ordered by. Example: `metadata["test_scenario"] desc` | ### ListRunsResponse The response of a call to `RunService_ListRuns` containing requested runs. | Field | Type | Label | Description | | :---------------- | :---------- | :------- | :---------- | | runs | [Run](#run) | repeated | | | next\_page\_token | string | | | ### Run | Field | Type | Label | Description | | :--------------------- | :---------------------------------------------------------------- | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | run\_id | string | | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | organization\_id | string | | | | start\_time | google.protobuf.Timestamp | optional | | | stop\_time | google.protobuf.Timestamp | optional | | | is\_pinned | bool | | | | name | string | | | | description | string | | | | tags | string | repeated | | | default\_report\_id | string | | | | client\_key | string | optional | | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | The metadata values associated with this run. | | asset\_ids | string | repeated | | | archived\_date | google.protobuf.Timestamp | optional | | | is\_adhoc | bool | | | | is\_archived | bool | | Whether the Run is archived. This is inferred from whether archived\_date is set. | | duration | google.protobuf.Duration | optional | The duration of the run. Calculated as the difference between stop\_time and start\_time. If the run is ongoing (no stop\_time), this represents the duration from start\_time to current time. | ### StopRunRequest The request for a call to `RunService_StopRun` to stop a run. | Field | Type | Label | Description | | :------ | :----- | :---- | :---------- | | run\_id | string | | | ### StopRunResponse The response of a call to `RunService_StopRun` to stop a run. *This message has no fields.* ### UpdateRunRequest The request for a call to `RunService_UpdateRun` to update an existing run. | Field | Type | Label | Description | | :----------- | :------------------------------------------------------ | :---- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | run | [Run](#run) | | The run to update. The run's `run_id` field is used to identify the run to update and is required. | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The list of fields to be updated. The fields available to be updated are `name`, `description`, `start_time`, `stop_time`, `is_pinned`, `client_key`, `tags`,`is_archived`, and `metadata`. Important Note: When updating the `start_time`, please be aware that if a subsequent data ingestion commences for this run, the `start_time` will be automatically overwritten and set to the timestamp corresponding to the beginning of the latest run. Additionally, `client_key` can only be set once either in run creation or in update. Any subsequent attempt to update `client_key` will result in an error. | ### UpdateRunResponse The response of a call to `RunService_UpdateRun` containing the updated run. | Field | Type | Label | Description | | :---- | :---------- | :---- | :---------- | | run | [Run](#run) | | | ### ValidateRunFilterRequest The request for a call to `RunService_ValidateRunFilter`. | Field | Type | Label | Description | | :----- | :----- | :---- | :------------------------------------- | | filter | string | | The CEL filter expression to validate. | ### ValidateRunFilterResponse The response of a call to `RunService_ValidateRunFilter`. | Field | Type | Label | Description | | :------------- | :----- | :---- | :------------------------------------------------------------------------------------ | | error\_message | string | | Empty string if the filter is valid; otherwise contains the validation error message. | ## Enums *Allowed constant values used in message fields.* # saved_searches Source: https://docs.siftstack.com/api/reference/protocol-buffers/saved_searches sift/saved_searches/v1/saved_searches.proto ## Services *RPC methods exposed by this API.* ### SavedSearchService | Method | Request | Response | Description | | :----------------------- | :------------------------------------------------------------------ | :-------------------------------------------------------------------- | :------------------------------------------------------------------------------------------ | | GetSavedSearch | [GetSavedSearchRequest](#getsavedsearchrequest) | [GetSavedSearchResponse](#getsavedsearchresponse) | Retrieve a saved search. | | CreateSavedSearch | [CreateSavedSearchRequest](#createsavedsearchrequest) | [CreateSavedSearchResponse](#createsavedsearchresponse) | Create a saved search. | | ListSavedSearches | [ListSavedSearchesRequest](#listsavedsearchesrequest) | [ListSavedSearchesResponse](#listsavedsearchesresponse) | List saved searches. | | UpdateSavedSearch | [UpdateSavedSearchRequest](#updatesavedsearchrequest) | [UpdateSavedSearchResponse](#updatesavedsearchresponse) | Updates an existing saved search using using the list of fields specified in `update_mask`. | | DeleteSavedSearch | [DeleteSavedSearchRequest](#deletesavedsearchrequest) | [DeleteSavedSearchResponse](#deletesavedsearchresponse) | Delete a saved search. | | BatchDeleteSavedSearches | [BatchDeleteSavedSearchesRequest](#batchdeletesavedsearchesrequest) | [BatchDeleteSavedSearchesResponse](#batchdeletesavedsearchesresponse) | Batch deletes saved searches. | ## Messages *Data models used across requests/responses.* ### BatchDeleteSavedSearchesRequest The request for a call to `SavedSearchService_BatchDeleteSavedSearches` to delete saved searches. | Field | Type | Label | Description | | :----------------- | :----- | :------- | :------------------------------- | | saved\_search\_ids | string | repeated | Limit of 1000 searches per batch | ### BatchDeleteSavedSearchesResponse The response of a call to `SavedSearchService_BatchDeleteSavedSearches`. *This message has no fields.* ### CreateSavedSearchRequest The request for a call to `SavedSearchService_CreateSavedSearch` to create a saved search. | Field | Type | Label | Description | | :--------------- | :---------------------------------------------- | :---- | :-------------------------------------------------------------------------- | | name | string | | | | properties | [SavedSearchProperties](#savedsearchproperties) | | | | organization\_id | string | | This field is only required if your user belongs to multiple organizations. | ### CreateSavedSearchResponse The response for a call to `SavedSearchService_CreateSavedResponse`. | Field | Type | Label | Description | | :------------ | :-------------------------- | :---- | :---------- | | saved\_search | [SavedSearch](#savedsearch) | | | ### DeleteSavedSearchRequest The request for a call to `SavedSearchService_DeleteSavedSearch` to delete a saved search. | Field | Type | Label | Description | | :---------------- | :----- | :---- | :---------- | | saved\_search\_id | string | | | ### DeleteSavedSearchResponse The response of a call to `SavedSearchService_DeleteSavedSearch`. *This message has no fields.* ### GetSavedSearchRequest The request for a call to `SavedSearchService_GetSavedSearch` to retrieve a saved search; | Field | Type | Label | Description | | :---------------- | :----- | :---- | :---------- | | saved\_search\_id | string | | | ### GetSavedSearchResponse The response of a call to `SavedSearchService_GetSavedSearch`. | Field | Type | Label | Description | | :------------ | :-------------------------- | :---- | :---------- | | saved\_search | [SavedSearch](#savedsearch) | | | ### ListSavedSearchesRequest The request for a call to `SavedSearchService_ListSavedSearches` to retrieve saved searches. | Field | Type | Label | Description | | :--------------- | :----- | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of saved searches to return. The service may return fewer than this value. If unspecified, at most 50 saved searches will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListSavedSearches` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListSavedSearches` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are 'name', 'saved\_search\_id', and 'overview\_mode'. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | organization\_id | string | | This field is only required if your user belongs to multiple organizations. | | order\_by | string | | How to order the retrieved saved searches. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `name`, `created_date`, and `modified_date`. If left empty, items are ordered by `created_date` in ascending order (oldest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | ### ListSavedSearchesResponse The response of a call to `SavedSearchService_ListSavedSearchesResponse`. | Field | Type | Label | Description | | :---------------- | :-------------------------- | :------- | :---------- | | saved\_searches | [SavedSearch](#savedsearch) | repeated | | | next\_page\_token | string | | | ### SavedSearch | Field | Type | Label | Description | | :--------------------- | :---------------------------------------------- | :---- | :---------- | | saved\_search\_id | string | | | | organization\_id | string | | | | name | string | | | | properties | [SavedSearchProperties](#savedsearchproperties) | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | ### SavedSearchFilterItem | Field | Type | Label | Description | | :---- | :----- | :---- | :---------- | | id | string | | | | name | string | | | ### SavedSearchMetadataItem | Field | Type | Label | Description | | :-------------------------- | :----- | :---- | :---------- | | key | string | | | | oneof value. string\_value | string | | | | oneof value. number\_value | double | | | | oneof value. boolean\_value | bool | | | ### SavedSearchProperties | Field | Type | Label | Description | | :---------------------- | :-------------------------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | overview\_mode | string | | | | search\_term | string | optional | | | from\_date\_time | google.protobuf.Timestamp | optional | | | to\_date\_time | google.protobuf.Timestamp | optional | | | asset\_items | [SavedSearchFilterItem](#savedsearchfilteritem) | repeated | | | user\_items | [SavedSearchFilterItem](#savedsearchfilteritem) | repeated | | | tag\_items | [SavedSearchFilterItem](#savedsearchfilteritem) | repeated | | | annotation\_items | [SavedSearchFilterItem](#savedsearchfilteritem) | repeated | | | run\_items | [SavedSearchFilterItem](#savedsearchfilteritem) | repeated | | | report\_template\_items | [SavedSearchFilterItem](#savedsearchfilteritem) | repeated | Superseded by `template_items`, which also carries canvases. Saved searches written before that field exists only populate this one, and reads hydrate `template_items` from it with `kind` set to "reportTemplate". | | show\_advanced\_filters | bool | optional | | | include\_archived | bool | optional | | | order\_by | string | optional | | | metadata\_items | [SavedSearchMetadataItem](#savedsearchmetadataitem) | repeated | | | duration | string | optional | | | template\_items | [SavedSearchTemplateItem](#savedsearchtemplateitem) | repeated | Reports search: report templates and canvases are stored together in a single filter. | | report\_type | string | optional | Reports search: restricts results to a single report kind. One of "RULE\_EVALUATION" or "CANVAS", matching the `report_type` filter values. | ### SavedSearchTemplateItem A report template or canvas selected in the reports Template filter. Distinct from `SavedSearchFilterItem`, which is shared by filters that have no kind. | Field | Type | Label | Description | | :---- | :----- | :---- | :----------------------------------- | | id | string | | | | name | string | | | | kind | string | | One of "reportTemplate" or "canvas". | ### UpdateSavedSearchRequest The request for a call to `SavedSearchService_UpdateSavedSearch` to update a saved search. | Field | Type | Label | Description | | :------------ | :------------------------------------------------------ | :---- | :------------------------------------------------------------------------------------------------ | | saved\_search | [SavedSearch](#savedsearch) | | The saved search to update. | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The list of fields to be updated. The fields available to be updated are `name` and `properties`. | ### UpdateSavedSearchResponse The response of a call to `SavedSearchService_UpdateSavedSearch`. | Field | Type | Label | Description | | :------------ | :-------------------------- | :---- | :---------- | | saved\_search | [SavedSearch](#savedsearch) | | | ## Enums *Allowed constant values used in message fields.* # tags Source: https://docs.siftstack.com/api/reference/protocol-buffers/tags sift/tags/v2/tags.proto ## Services *RPC methods exposed by this API.* ### TagService | Method | Request | Response | Description | | :-------- | :------------------------------------ | :-------------------------------------- | :--------------------------------------- | | CreateTag | [CreateTagRequest](#createtagrequest) | [CreateTagResponse](#createtagresponse) | Create a tag. | | ListTags | [ListTagsRequest](#listtagsrequest) | [ListTagsResponse](#listtagsresponse) | Retrieves tags using an optional filter. | ## Messages *Data models used across requests/responses.* ### CreateTagRequest The request for a call to TagService.CreateTag. | Field | Type | Label | Description | | :---- | :----- | :---- | :------------------------------------------------------------------------- | | name | string | | The name for the new tag. If the tag already exists, an error is returned. | ### CreateTagResponse The result of a call to TagService.CreateTag. | Field | Type | Label | Description | | :---- | :---------- | :---- | :---------- | | tag | [Tag](#tag) | | | ### ListTagsRequest | Field | Type | Label | Description | | :---------- | :------------------ | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | page\_size | uint32 | | The maximum number of tags to return. The service may return fewer than this value. If unspecified, at most 50 tags will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. | | page\_token | string | | A page token, received from a previous `ListTags` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListTags` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string Available fields to filter by are 'name' and 'tag\_id'. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved campaigns. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `created_date` and `name`. If left empty, items are ordered by `created_date` in ascending order (oldest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,name" | | tag\_type | [TagType](#tagtype) | | Narrows the tags selected to a specific type. | ### ListTagsResponse | Field | Type | Label | Description | | :---------------- | :---------- | :------- | :--------------------------------------------------------------------------------------------------------------------------- | | tags | [Tag](#tag) | repeated | | | next\_page\_token | string | | A token, which can be sent as `page_token` to retrieve the next page. If this field is empty, there are no subsequent pages. | ### Tag | Field | Type | Label | Description | | :-------------------- | :------------------------ | :---- | :---------- | | tag\_id | string | | | | name | string | | | | created\_by\_user\_id | string | | | | created\_date | google.protobuf.Timestamp | | | ## Enums *Allowed constant values used in message fields.* ### TagType | Name | Number | Description | | :-------------------------- | :----- | :---------- | | TAG\_TYPE\_UNSPECIFIED | 0 | | | TAG\_TYPE\_ANNOTATION | 1 | | | TAG\_TYPE\_ASSET | 2 | | | TAG\_TYPE\_CAMPAIGN | 3 | | | TAG\_TYPE\_REPORT | 4 | | | TAG\_TYPE\_REPORT\_TEMPLATE | 5 | | | TAG\_TYPE\_RUN | 6 | | # test_reports Source: https://docs.siftstack.com/api/reference/protocol-buffers/test_reports sift/test_reports/v1/test_reports.proto ## Services *RPC methods exposed by this API.* ### TestReportService | Method | Request | Response | Description | | :--------------------- | :-------------------------------------------------------------- | :---------------------------------------------------------------- | :----------------------------------------------------- | | ImportTestReport | [ImportTestReportRequest](#importtestreportrequest) | [ImportTestReportResponse](#importtestreportresponse) | Imports a test report from an already-uploaded file | | CreateTestReport | [CreateTestReportRequest](#createtestreportrequest) | [CreateTestReportResponse](#createtestreportresponse) | Creates a test report | | GetTestReport | [GetTestReportRequest](#gettestreportrequest) | [GetTestReportResponse](#gettestreportresponse) | Gets a single test report | | ListTestReports | [ListTestReportsRequest](#listtestreportsrequest) | [ListTestReportsResponse](#listtestreportsresponse) | Lists test reports with optional filtering | | UpdateTestReport | [UpdateTestReportRequest](#updatetestreportrequest) | [UpdateTestReportResponse](#updatetestreportresponse) | Updates a test report | | DeleteTestReport | [DeleteTestReportRequest](#deletetestreportrequest) | [DeleteTestReportResponse](#deletetestreportresponse) | Deletes a test report | | CreateTestStep | [CreateTestStepRequest](#createteststeprequest) | [CreateTestStepResponse](#createteststepresponse) | Creates a test step | | ListTestSteps | [ListTestStepsRequest](#listteststepsrequest) | [ListTestStepsResponse](#listteststepsresponse) | Lists test steps with optional filtering | | UpdateTestStep | [UpdateTestStepRequest](#updateteststeprequest) | [UpdateTestStepResponse](#updateteststepresponse) | Updates a test step | | DeleteTestStep | [DeleteTestStepRequest](#deleteteststeprequest) | [DeleteTestStepResponse](#deleteteststepresponse) | Deletes a test step | | CreateTestMeasurement | [CreateTestMeasurementRequest](#createtestmeasurementrequest) | [CreateTestMeasurementResponse](#createtestmeasurementresponse) | Creates a test measurement | | CreateTestMeasurements | [CreateTestMeasurementsRequest](#createtestmeasurementsrequest) | [CreateTestMeasurementsResponse](#createtestmeasurementsresponse) | Creates multiple test measurements in a single request | | ListTestMeasurements | [ListTestMeasurementsRequest](#listtestmeasurementsrequest) | [ListTestMeasurementsResponse](#listtestmeasurementsresponse) | Lists test measurements with optional filtering | | CountTestSteps | [CountTestStepsRequest](#countteststepsrequest) | [CountTestStepsResponse](#countteststepsresponse) | Counts test steps with optional filtering | | CountTestMeasurements | [CountTestMeasurementsRequest](#counttestmeasurementsrequest) | [CountTestMeasurementsResponse](#counttestmeasurementsresponse) | Counts test measurements with optional filtering | | UpdateTestMeasurement | [UpdateTestMeasurementRequest](#updatetestmeasurementrequest) | [UpdateTestMeasurementResponse](#updatetestmeasurementresponse) | Updates a test measurement | | DeleteTestMeasurement | [DeleteTestMeasurementRequest](#deletetestmeasurementrequest) | [DeleteTestMeasurementResponse](#deletetestmeasurementresponse) | Deletes a test measurement | ## Messages *Data models used across requests/responses.* ### CountTestMeasurementsRequest Request message for CountTestMeasurements | Field | Type | Label | Description | | :----- | :----- | :---- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `measurement_id`, `measurement_type`, `name`, `test_step_id`, `test_report_id`, `numeric_value`, `string_value`, `boolean_value`, `passed`, `timestamp`, `created_date`, `modified_date`, and `metadata`. Metadata can be used in filters by using `metadata.{metadata_key_name}` as the field name. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | ### CountTestMeasurementsResponse Response message for CountTestMeasurements | Field | Type | Label | Description | | :---- | :---- | :---- | :------------------------------------------------------- | | count | int64 | | The total count of test measurements matching the filter | ### CountTestStepsRequest Request message for CountTestSteps | Field | Type | Label | Description | | :----- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `test_step_id`, `test_report_id`, `parent_step_id`, `name`, `description`, `step_type`, `step_path`, `status`, `start_time`, `end_time`, `error_code`, `error_message`, `created_date`, `modified_date`, and `metadata`. Metadata can be used in filters by using `metadata.{metadata_key_name}` as the field name. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | ### CountTestStepsResponse Response message for CountTestSteps | Field | Type | Label | Description | | :---- | :---- | :---- | :------------------------------------------------ | | count | int64 | | The total count of test steps matching the filter | ### CreateTestMeasurementRequest Request message for CreateTestMeasurement | Field | Type | Label | Description | | :---------------- | :---------------------------------- | :---- | :----------------------------- | | test\_measurement | [TestMeasurement](#testmeasurement) | | The test measurement to create | ### CreateTestMeasurementResponse Response message for CreateTestMeasurement | Field | Type | Label | Description | | :---------------- | :---------------------------------- | :---- | :--------------------------- | | test\_measurement | [TestMeasurement](#testmeasurement) | | The created test measurement | ### CreateTestMeasurementsRequest Request message for CreateTestMeasurements | Field | Type | Label | Description | | :----------------- | :---------------------------------- | :------- | :------------------------------ | | test\_measurements | [TestMeasurement](#testmeasurement) | repeated | The test measurements to create | ### CreateTestMeasurementsResponse Response message for CreateTestMeasurements | Field | Type | Label | Description | | :--------------------------- | :----- | :------- | :--------------------------------------------------- | | measurements\_created\_count | int32 | | The number of test measurements successfully created | | measurement\_ids | string | repeated | The IDs of the created test measurements | ### CreateTestReportRequest Request message for CreateTestReport | Field | Type | Label | Description | | :----------------- | :---------------------------------------------------------------- | :------- | :------------------------------------------------ | | status | [TestStatus](#teststatus) | | The status of the test run | | name | string | | The name of the test run | | test\_system\_name | string | | The name of the test system | | test\_case | string | | The test case that was run | | start\_time | google.protobuf.Timestamp | | The start time of the test run | | end\_time | google.protobuf.Timestamp | | The end time of the test run | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | The metadata values associated with this test run | | serial\_number | string | | The serial number for the DUT | | part\_number | string | | The part number for the DUT | | system\_operator | string | | Unique identifier for user owner | | run\_id | string | | The run ID for the test report | ### CreateTestReportResponse Response message for CreateTestReport | Field | Type | Label | Description | | :----------- | :------------------------ | :---- | :---------------------- | | test\_report | [TestReport](#testreport) | | The created test report | ### CreateTestStepRequest Request message for CreateTestStep | Field | Type | Label | Description | | :--------- | :-------------------- | :---- | :---------------------- | | test\_step | [TestStep](#teststep) | | The test step to create | ### CreateTestStepResponse Response message for CreateTestStep | Field | Type | Label | Description | | :--------- | :-------------------- | :---- | :-------------------- | | test\_step | [TestStep](#teststep) | | The created test step | ### DeleteTestMeasurementRequest Request message for DeleteTestMeasurement | Field | Type | Label | Description | | :-------------- | :----- | :---- | :--------------------------------------- | | measurement\_id | string | | The ID of the test measurement to delete | ### DeleteTestMeasurementResponse Response message for DeleteTestMeasurement Empty response indicating successful deletion *This message has no fields.* ### DeleteTestReportRequest Request message for DeleteTestReport | Field | Type | Label | Description | | :--------------- | :----- | :---- | :---------------------------------- | | test\_report\_id | string | | The ID of the test report to delete | ### DeleteTestReportResponse Response message for DeleteTestReport Empty response indicating successful deletion *This message has no fields.* ### DeleteTestStepRequest Request message for DeleteTestStep | Field | Type | Label | Description | | :------------- | :----- | :---- | :-------------------------------- | | test\_step\_id | string | | The ID of the test step to delete | ### DeleteTestStepResponse Response message for DeleteTestStep Empty response indicating successful deletion *This message has no fields.* ### ErrorInfo | Field | Type | Label | Description | | :------------- | :----- | :---- | :---------- | | error\_code | int32 | | | | error\_message | string | | | ### GetTestReportRequest Request message for GetTestReport | Field | Type | Label | Description | | :------------------------------- | :----- | :---- | :-------------------------------------------------------------------------------------------------------------------------------------------- | | test\_report\_id | string | | The ID of the test report to get | | include\_overall\_modified\_date | bool | | When true, populate TestReport.overall\_modified\_date. This requires an aggregate over the report's steps and measurements, so it is opt-in. | ### GetTestReportResponse Response message for GetTestReport | Field | Type | Label | Description | | :----------- | :------------------------ | :---- | :-------------- | | test\_report | [TestReport](#testreport) | | The test report | ### ImportTestReportRequest Request message for ImportTestReport | Field | Type | Label | Description | | :--------------- | :----- | :---- | :---------------------------------------------- | | remote\_file\_id | string | | The remote file ID containing the XML test data | ### ImportTestReportResponse Response message for ImportTestReport | Field | Type | Label | Description | | :----------- | :------------------------ | :---- | :----------------------- | | test\_report | [TestReport](#testreport) | | The imported test report | ### ListTestMeasurementsRequest Request message for ListTestMeasurements | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of test measurements to return. The service may return fewer than this value. If unspecified, at most 50 test measurements will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. | | page\_token | string | | A page token, received from a previous `ListTestMeasurements` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListTestMeasurements` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `measurement_id`, `measurement_type`, `name`, `test_step_id`, `test_report_id`, `numeric_value`, `string_value`, `boolean_value`, `passed`, `timestamp`, `created_date`, `modified_date`, and `metadata`. Metadata can be used in filters by using `metadata.{metadata_key_name}` as the field name. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved test measurements. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `measurement_id`, `name`, `measurement_type`, `test_step_id`, `test_report_id`, `passed`, `timestamp`, `created_date`, and `modified_date`. If left empty, items are ordered by `timestamp` in ascending order. For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "timestamp asc,name" | ### ListTestMeasurementsResponse Response message for ListTestMeasurements | Field | Type | Label | Description | | :----------------- | :---------------------------------- | :------- | :--------------------------------- | | test\_measurements | [TestMeasurement](#testmeasurement) | repeated | The list of test measurements | | next\_page\_token | string | | The next page token for pagination | ### ListTestReportsRequest Request message for ListTestReports | Field | Type | Label | Description | | :---------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | page\_size | uint32 | | The maximum number of test reports to return. The service may return fewer than this value. If unspecified, at most 50 test reports will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. | | page\_token | string | | A page token, received from a previous `ListTestReports` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListTestReports` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `test_report_id`, `status`, `name`, `test_system_name`, `test_case`, `start_time`, `end_time`, `serial_number`, `created_by_user_id`, `modified_by_user_id`, `part_number`, `system_operator`, `run_id`, `archived_date`, and `metadata`. Metadata can be used in filters by using `metadata.{metadata_key_name}` as the field name. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved test reports. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `test_report_id`, `name`, `test_system_name`, `test_case`, `start_time`, `end_time`, `created_date`, and `modified_date`. If left empty, items are ordered by `start_time` in descending order (newest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "start\_time desc,name" | ### ListTestReportsResponse Response message for ListTestReports | Field | Type | Label | Description | | :---------------- | :------------------------ | :------- | :--------------------------------- | | test\_reports | [TestReport](#testreport) | repeated | The list of test reports | | next\_page\_token | string | | The next page token for pagination | ### ListTestStepsRequest Request message for ListTestSteps | Field | Type | Label | Description | | :---------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of test steps to return. The service may return fewer than this value. If unspecified, at most 50 test steps will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. | | page\_token | string | | A page token, received from a previous `ListTestSteps` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListTestSteps` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `test_step_id`, `test_report_id`, `parent_step_id`, `name`, `description`, `step_type`, `step_path`, `status`, `start_time`, `end_time`, `error_code`, `error_message`, `created_date`, `modified_date`, and `metadata`. Metadata can be used in filters by using `metadata.{metadata_key_name}` as the field name. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved test steps. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `test_step_id`, `name`, `step_type`, `step_path`, `status`, `start_time`, `end_time`, `created_date`, and `modified_date`. If left empty, items are ordered by `step_path` in ascending order. For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "step\_path asc,start\_time desc" | ### ListTestStepsResponse Response message for ListTestSteps | Field | Type | Label | Description | | :---------------- | :-------------------- | :------- | :--------------------------------- | | test\_steps | [TestStep](#teststep) | repeated | The list of test steps | | next\_page\_token | string | | The next page token for pagination | ### NumericBounds | Field | Type | Label | Description | | :---- | :----- | :------- | :---------- | | min | double | optional | | | max | double | optional | | ### StringBounds | Field | Type | Label | Description | | :-------------- | :----- | :---- | :---------- | | expected\_value | string | | | ### TestMeasurement | Field | Type | Label | Description | | :---------------------------- | :---------------------------------------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------- | | measurement\_id | string | | | | measurement\_type | [TestMeasurementType](#testmeasurementtype) | | | | name | string | | | | test\_step\_id | string | | | | test\_report\_id | string | | | | oneof value. numeric\_value | double | | | | oneof value. string\_value | string | | | | oneof value. boolean\_value | bool | | | | unit | [sift.unit.v2.Unit](#sift-unit-v2-unit) | | | | oneof bounds. numeric\_bounds | [NumericBounds](#numericbounds) | | | | oneof bounds. string\_bounds | [StringBounds](#stringbounds) | | | | passed | bool | | | | timestamp | google.protobuf.Timestamp | | | | description | string | | Description or note about the measurement | | channel\_names | string | repeated | Names of Sift channels this measurement is associated with. Allows cross-plotting in Explore using the Report's associated Run to resolve channels from names. | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | The metadata values associated with this measurement | ### TestReport | Field | Type | Label | Description | | :---------------------- | :---------------------------------------------------------------- | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------- | | test\_report\_id | string | | Unique identifier for the run | | status | [TestStatus](#teststatus) | | The status of the test run | | name | string | | The name of the test run | | test\_system\_name | string | | The name of the test system | | test\_case | string | | The test case that was run | | start\_time | google.protobuf.Timestamp | | The start time of the test run | | end\_time | google.protobuf.Timestamp | | The end time of the test run | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | The metadata values associated with this test run | | serial\_number | string | | The serial number for the DUT | | part\_number | string | | The part number for the DUT | | system\_operator | string | | Unique identifier for user owner | | archived\_date | google.protobuf.Timestamp | | The date and time the test run was archived (internal) | | is\_archived | bool | | Whether the test run is archived (externally exposed) | | run\_id | string | | The run ID for the test run | | overall\_modified\_date | google.protobuf.Timestamp | | The most recent write to this report or to any of its steps or measurements. Only populated when GetTestReport is called with include\_overall\_modified\_date. | ### TestStep | Field | Type | Label | Description | | :--------------- | :---------------------------------------------------------------- | :------- | :------------------------------------------------- | | test\_step\_id | string | | unique identifier for the step | | test\_report\_id | string | | pointer to overall test run | | parent\_step\_id | string | | pointer to parent step, if any | | name | string | | Name of the test step for display | | description | string | | Description of the test step from test controller | | step\_type | [TestStepType](#teststeptype) | | Semantic type of the test step | | step\_path | string | | Hierarchical path (e.g., "1", "1.1", "1.2.3") | | status | [TestStatus](#teststatus) | | Status of the test step | | start\_time | google.protobuf.Timestamp | | Start time of the test step | | end\_time | google.protobuf.Timestamp | | End time of the test step | | error\_info | [ErrorInfo](#errorinfo) | | Error information of the test step | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | The metadata values associated with this test step | ### UpdateTestMeasurementRequest Request message for UpdateTestMeasurement | Field | Type | Label | Description | | :---------------- | :------------------------------------------------------ | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | test\_measurement | [TestMeasurement](#testmeasurement) | | The test measurement to update | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The field mask specifying which fields to update. The fields available to be updated are `name`, `measurement_type`, `numeric_value`, `string_value`, `boolean_value`, `unit`, `numeric_bounds`, `string_bounds`, `passed`, `timestamp`, `description`, and `channel_names` and `metadata`. When `metadata` is in the mask, the supplied list replaces all existing metadata for the measurement; sending an empty or omitted list clears all metadata. | ### UpdateTestMeasurementResponse Response message for UpdateTestMeasurement | Field | Type | Label | Description | | :---------------- | :---------------------------------- | :---- | :--------------------------- | | test\_measurement | [TestMeasurement](#testmeasurement) | | The updated test measurement | ### UpdateTestReportRequest Request message for UpdateTestReport | Field | Type | Label | Description | | :----------- | :------------------------------------------------------ | :---- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | test\_report | [TestReport](#testreport) | | The test report to update | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The field mask specifying which fields to update. The fields available to be updated are `status`, `name`, `test_system_name`, `test_case`, `start_time`, `end_time`, `serial_number`, `part_number`, `system_operator`, `run_id`, and `is_archived`. | ### UpdateTestReportResponse Response message for UpdateTestReport | Field | Type | Label | Description | | :----------- | :------------------------ | :---- | :---------------------- | | test\_report | [TestReport](#testreport) | | The updated test report | ### UpdateTestStepRequest Request message for UpdateTestStep | Field | Type | Label | Description | | :----------- | :------------------------------------------------------ | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | test\_step | [TestStep](#teststep) | | The test step to update | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The field mask specifying which fields to update. The fields available to be updated are `name`, `description`, `step_type`, `step_path`, `test_case`, `status`, `start_time`, `end_time`, `error_info`, and `metadata`. When `metadata` is in the mask, the supplied list replaces all existing metadata for the test step; sending an empty or omitted list clears all metadata. | ### UpdateTestStepResponse Response message for UpdateTestStep | Field | Type | Label | Description | | :--------- | :-------------------- | :---- | :-------------------- | | test\_step | [TestStep](#teststep) | | The updated test step | ## Enums *Allowed constant values used in message fields.* ### TestMeasurementType | Name | Number | Description | | :----------------------------------- | :----- | :---------- | | TEST\_MEASUREMENT\_TYPE\_UNSPECIFIED | 0 | | | TEST\_MEASUREMENT\_TYPE\_DOUBLE | 1 | | | TEST\_MEASUREMENT\_TYPE\_STRING | 3 | | | TEST\_MEASUREMENT\_TYPE\_BOOLEAN | 4 | | | TEST\_MEASUREMENT\_TYPE\_LIMIT | 5 | | ### TestStatus | Name | Number | Description | | :------------------------- | :----- | :--------------------------------------------------------- | | TEST\_STATUS\_UNSPECIFIED | 0 | | | TEST\_STATUS\_DRAFT | 1 | Barebones test report created, waiting for file processing | | TEST\_STATUS\_PASSED | 2 | | | TEST\_STATUS\_FAILED | 3 | | | TEST\_STATUS\_ABORTED | 4 | | | TEST\_STATUS\_ERROR | 5 | | | TEST\_STATUS\_IN\_PROGRESS | 6 | | | TEST\_STATUS\_SKIPPED | 7 | | ### TestStepType | Name | Number | Description | | :------------------------------ | :----- | :----------------------------------------------- | | TEST\_STEP\_TYPE\_UNSPECIFIED | 0 | | | TEST\_STEP\_TYPE\_SEQUENCE | 1 | ResultSet/MainSequence - top-level test sequence | | TEST\_STEP\_TYPE\_GROUP | 2 | TestGroup - logical grouping of test steps | | TEST\_STEP\_TYPE\_ACTION | 3 | SessionAction - individual executable action | | TEST\_STEP\_TYPE\_FLOW\_CONTROL | 4 | Flow control elements (While, If, etc.) | # unit Source: https://docs.siftstack.com/api/reference/protocol-buffers/unit sift/unit/v2/unit.proto ## Services *RPC methods exposed by this API.* ### UnitService | Method | Request | Response | Description | | :--------- | :-------------------------------------- | :---------------------------------------- | :---------- | | CreateUnit | [CreateUnitRequest](#createunitrequest) | [CreateUnitResponse](#createunitresponse) | | | ListUnits | [ListUnitsRequest](#listunitsrequest) | [ListUnitsResponse](#listunitsresponse) | | ## Messages *Data models used across requests/responses.* ### CreateUnitRequest | Field | Type | Label | Description | | :---- | :----- | :---- | :---------- | | name | string | | | ### CreateUnitResponse | Field | Type | Label | Description | | :---- | :------------ | :---- | :---------- | | unit | [Unit](#unit) | | | ### ListUnitsRequest | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of units to return. The service may return fewer than this value. If unspecified, at most 50 units will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. | | page\_token | string | | A page token, received from a previous `ListUnits` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListUnits` must match the call that provided the page token. | | filter | string | | A Common Expression Language (CEL, [https://github.com/google/cel-spec](https://github.com/google/cel-spec)) filter string. Available tag variables are: - abbreviated\_name - name - created\_date - unit\_id | | order\_by | string | | How to order the retrieved campaigns. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `name`, `created_date`, and `abbreviated_name`. If left empty, items are ordered by `created_date` in ascending order (oldest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,abbreviated\_name" | ### ListUnitsResponse | Field | Type | Label | Description | | :---------------- | :------------ | :------- | :--------------------------------------------------------------------------------------------------------------------------- | | units | [Unit](#unit) | repeated | | | next\_page\_token | string | | A token, which can be sent as `page_token` to retrieve the next page. If this field is empty, there are no subsequent pages. | ### Unit | Field | Type | Label | Description | | :---------------- | :----- | :---- | :---------- | | unit\_id | string | | | | abbreviated\_name | string | | | ## Enums *Allowed constant values used in message fields.* # user Source: https://docs.siftstack.com/api/reference/protocol-buffers/user sift/common/type/v1/user.proto ## Services *RPC methods exposed by this API.* ## Messages *Data models used across requests/responses.* ### User | Field | Type | Label | Description | | :------------ | :---------------------------- | :------- | :---------- | | user\_id | string | | | | user\_name | string | | | | organizations | [Organization](#organization) | repeated | | ## Enums *Allowed constant values used in message fields.* # user_defined_functions Source: https://docs.siftstack.com/api/reference/protocol-buffers/user_defined_functions sift/common/type/v1/user_defined_functions.proto ## Services *RPC methods exposed by this API.* ## Messages *Data models used across requests/responses.* ### FunctionDependency | Field | Type | Label | Description | | :----------------------------------- | :----- | :---- | :---------- | | user\_defined\_function\_version\_id | string | | | ### FunctionInput | Field | Type | Label | Description | | :--------- | :------------------------------------ | :---- | :---------- | | identifier | string | | | | data\_type | [FunctionDataType](#functiondatatype) | | | | constant | bool | | | ### UserDefinedFunction | Field | Type | Label | Description | | :----------------------------------- | :---------------------------------------------------------------- | :------- | :---------- | | user\_defined\_function\_id | string | | | | name | string | | | | archived\_date | google.protobuf.Timestamp | optional | | | user\_defined\_function\_version\_id | string | | | | version | uint32 | | | | description | string | | | | change\_message | string | | | | user\_notes | string | | | | expression | string | | | | function\_inputs | [FunctionInput](#functioninput) | repeated | | | function\_output\_type | [FunctionDataType](#functiondatatype) | | | | function\_dependencies | [FunctionDependency](#functiondependency) | repeated | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | metadata | [sift.metadata.v1.MetadataValue](#sift-metadata-v1-metadatavalue) | repeated | | | is\_archived | bool | | | ## Enums *Allowed constant values used in message fields.* ### FunctionDataType | Name | Number | Description | | :-------------------------------- | :----- | :---------- | | FUNCTION\_DATA\_TYPE\_UNSPECIFIED | 0 | | | FUNCTION\_DATA\_TYPE\_NUMERIC | 1 | | | FUNCTION\_DATA\_TYPE\_STRING | 2 | | | FUNCTION\_DATA\_TYPE\_BOOL | 3 | | # user_groups Source: https://docs.siftstack.com/api/reference/protocol-buffers/user_groups sift/user_groups/v2/user_groups.proto ## Services *RPC methods exposed by this API.* ### UserGroupService | Method | Request | Response | Description | | :---------------------- | :---------------------------------------------------------------- | :------------------------------------------------------------------ | :---------- | | ListUserGroups | [ListUserGroupsRequest](#listusergroupsrequest) | [ListUserGroupsResponse](#listusergroupsresponse) | | | GetUserGroup | [GetUserGroupRequest](#getusergrouprequest) | [GetUserGroupResponse](#getusergroupresponse) | | | CreateUserGroup | [CreateUserGroupRequest](#createusergrouprequest) | [CreateUserGroupResponse](#createusergroupresponse) | | | UpdateUserGroup | [UpdateUserGroupRequest](#updateusergrouprequest) | [UpdateUserGroupResponse](#updateusergroupresponse) | | | DeleteUserGroup | [DeleteUserGroupRequest](#deleteusergrouprequest) | [DeleteUserGroupResponse](#deleteusergroupresponse) | | | AddUserToUserGroup | [AddUserToUserGroupRequest](#addusertousergrouprequest) | [AddUserToUserGroupResponse](#addusertousergroupresponse) | | | RemoveUserFromUserGroup | [RemoveUserFromUserGroupRequest](#removeuserfromusergrouprequest) | [RemoveUserFromUserGroupResponse](#removeuserfromusergroupresponse) | | | UpdateUserUserGroups | [UpdateUserUserGroupsRequest](#updateuserusergroupsrequest) | [UpdateUserUserGroupsResponse](#updateuserusergroupsresponse) | | | GetUserGroupsForAssets | [GetUserGroupsForAssetsRequest](#getusergroupsforassetsrequest) | [GetUserGroupsForAssetsResponse](#getusergroupsforassetsresponse) | | ## Messages *Data models used across requests/responses.* ### AddUserToUserGroupRequest | Field | Type | Label | Description | | :-------------- | :----- | :---- | :---------- | | user\_group\_id | string | | | | user\_id | string | | | ### AddUserToUserGroupResponse *This message has no fields.* ### CreateUserGroupRequest | Field | Type | Label | Description | | :---------- | :---------------------- | :---- | :---------- | | user\_group | [UserGroup](#usergroup) | | | ### CreateUserGroupResponse | Field | Type | Label | Description | | :---------- | :---------------------- | :---- | :---------- | | user\_group | [UserGroup](#usergroup) | | | ### DeleteUserGroupRequest | Field | Type | Label | Description | | :-------------- | :----- | :---- | :---------- | | user\_group\_id | string | | | ### DeleteUserGroupResponse *This message has no fields.* ### GetUserGroupRequest | Field | Type | Label | Description | | :-------------- | :----- | :---- | :---------- | | user\_group\_id | string | | | ### GetUserGroupResponse | Field | Type | Label | Description | | :---------- | :---------------------- | :---- | :---------- | | user\_group | [UserGroup](#usergroup) | | | ### GetUserGroupsForAssetsRequest | Field | Type | Label | Description | | :--------- | :----- | :------- | :---------- | | asset\_ids | string | repeated | | ### GetUserGroupsForAssetsResponse | Field | Type | Label | Description | | :----------- | :---------------------------------------- | :------- | :---------- | | user\_groups | [UserGroup](#usergroup) | repeated | | | roles | [sift.roles.v2.Role](#sift-roles-v2-role) | repeated | | ### ListUserGroupsRequest | Field | Type | Label | Description | | :---------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | page\_size | uint32 | | The maximum number of user groups to return. The service may return fewer than this value. If unspecified, at most 50 will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. | | page\_token | string | | A page token, received from a previous `ListUserGroups` call. Provide this to retrieve the subsequent page. | When paginating, all other parameters provided to `ListUserGroups` must match the call that provided the page token. | \| filter | string | | A Common Expression Language (CEL, [https://github.com/google/cel-spec](https://github.com/google/cel-spec)) filter string. Available tag variables are: - name | \| order\_by | string | | How to order the retrieved user groups. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `name`, `created_date`, and `modified_date`. If left empty, items are ordered by `name` in ascending order (A-Z). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | ### ListUserGroupsResponse | Field | Type | Label | Description | | :---------------- | :---------------------- | :------- | :--------------------------------------------------------------------------------------------------------------------------- | | user\_groups | [UserGroup](#usergroup) | repeated | | | next\_page\_token | string | | A token, which can be sent as `page_token` to retrieve the next page. If this field is empty, there are no subsequent pages. | ### RemoveUserFromUserGroupRequest | Field | Type | Label | Description | | :-------------- | :----- | :---- | :---------- | | user\_group\_id | string | | | | user\_id | string | | | ### RemoveUserFromUserGroupResponse *This message has no fields.* ### UpdateUserGroupRequest | Field | Type | Label | Description | | :----------- | :------------------------------------------------------ | :---- | :---------------------------- | | user\_group | [UserGroup](#usergroup) | | | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The list of fields to update. | ### UpdateUserGroupResponse | Field | Type | Label | Description | | :---------- | :---------------------- | :---- | :---------- | | user\_group | [UserGroup](#usergroup) | | | ### UpdateUserUserGroupsRequest | Field | Type | Label | Description | | :--------------- | :----- | :------- | :---------- | | user\_id | string | | | | user\_group\_ids | string | repeated | | ### UpdateUserUserGroupsResponse *This message has no fields.* ### UserGroup | Field | Type | Label | Description | | :-------------- | :---------------------------------------- | :------- | :---------- | | user\_group\_id | string | | | | name | string | | | | role\_id | string | | | | is\_default | bool | | | | resources | [UserGroup.Resource](#usergroup-resource) | | | | user\_ids | string | repeated | | | is\_external | bool | | | ### UserGroup.Resource | Field | Type | Label | Description | | :---------- | :----- | :------- | :---------- | | asset\_ids | string | repeated | | | all\_assets | bool | | | ## Enums *Allowed constant values used in message fields.* # users Source: https://docs.siftstack.com/api/reference/protocol-buffers/users sift/users/v2/users.proto ## Services *RPC methods exposed by this API.* ### UserService | Method | Request | Response | Description | | :--------------------------- | :-------------------------------------------------------------------------- | :---------------------------------------------------------------------------- | :--------------------------------------------------------------- | | UpdateUserOrganizationActive | [UpdateUserOrganizationActiveRequest](#updateuserorganizationactiverequest) | [UpdateUserOrganizationActiveResponse](#updateuserorganizationactiveresponse) | Used to toggle a user's active status within their organization. | | GetUser | [GetUserRequest](#getuserrequest) | [GetUserResponse](#getuserresponse) | Retrieves a user object. | | ListActiveUsers | [ListActiveUsersRequest](#listactiveusersrequest) | [ListActiveUsersResponse](#listactiveusersresponse) | List active users. | | ListUsers | [ListUsersRequest](#listusersrequest) | [ListUsersResponse](#listusersresponse) | List users. | ## Messages *Data models used across requests/responses.* ### GetUserRequest The request for a call to retrieve a single existing user by its user\_id. | Field | Type | Label | Description | | :------- | :----- | :---- | :--------------------------------------------- | | user\_id | string | | The id of the asset to be retrieved. Required. | ### GetUserResponse | Field | Type | Label | Description | | :---- | :---------------------------------------------------- | :---- | :---------- | | user | [sift.common.type.v1.User](#sift-common-type-v1-user) | | | ### ListActiveUsersRequest The request for a call to `UserService_ListActiveUsers` to retrieve users. | Field | Type | Label | Description | | :--------------- | :----- | :---- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of users to return. The service may return fewer than this value. If unspecified, at most 50 users will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListActiveUsers` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListActiveUsers` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `user_id` and `name`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | organization\_id | string | | Optional. If provided, this will scope down the user search to just those in the organization ID provided. | | order\_by | string | | How to order the retrieved users. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are `name`, `created_date`, and `modified_date`. If left empty, items are ordered by `name` in ascending order (A-Z). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc,modified\_date" | ### ListActiveUsersResponse The response of a call to `UserService_ListActiveUsersResponse`. | Field | Type | Label | Description | | :---------------- | :---------------------------------------------------- | :------- | :---------- | | users | [sift.common.type.v1.User](#sift-common-type-v1-user) | repeated | | | next\_page\_token | string | | | ### ListUsersRequest The request for a call to `UserService_ListUsers` to retrieve users. | Field | Type | Label | Description | | :---------- | :----- | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of users to return. The service may return fewer than this value. If unspecified, at most 50 users will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. Optional. | | page\_token | string | | A page token, received from a previous `ListUsers` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListUsers` must match the call that provided the page token. Optional. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `user_id` and `name`. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | | order\_by | string | | How to order the retrieved users. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available fields to order\_by are: - created\_date - modified\_date | ### ListUsersResponse The response of a call to `UserService_ListUsersResponse`. | Field | Type | Label | Description | | :---------------- | :---------------------------------------------------- | :------- | :---------- | | users | [sift.common.type.v1.User](#sift-common-type-v1-user) | repeated | | | next\_page\_token | string | | | ### UpdateUserOrganizationActiveRequest | Field | Type | Label | Description | | :--------------- | :----- | :---- | :---------- | | user\_id | string | | | | organization\_id | string | | | | active | bool | | | ### UpdateUserOrganizationActiveResponse *This message has no fields.* ## Enums *Allowed constant values used in message fields.* # views Source: https://docs.siftstack.com/api/reference/protocol-buffers/views sift/views/v2/views.proto ## Services *RPC methods exposed by this API.* ### ViewService | Method | Request | Response | Description | | :------------------ | :-------------------------------------------------------- | :---------------------------------------------------------- | :---------------------------------------------------------------------------------- | | GetView | [GetViewRequest](#getviewrequest) | [GetViewResponse](#getviewresponse) | Retrieves a view. | | CreateView | [CreateViewRequest](#createviewrequest) | [CreateViewResponse](#createviewresponse) | Creates a view. | | UpdateView | [UpdateViewRequest](#updateviewrequest) | [UpdateViewResponse](#updateviewresponse) | Updates an existing view using using the list of fields specified in `update_mask`. | | ListViews | [ListViewsRequest](#listviewsrequest) | [ListViewsResponse](#listviewsresponse) | Retrieves views using an optional filter. | | ListApplicableViews | [ListApplicableViewsRequest](#listapplicableviewsrequest) | [ListApplicableViewsResponse](#listapplicableviewsresponse) | Lists views that apply to assets/runs. | | DeleteView | [DeleteViewRequest](#deleteviewrequest) | [DeleteViewResponse](#deleteviewresponse) | Deletes a view. | | PinView | [PinViewRequest](#pinviewrequest) | [PinViewResponse](#pinviewresponse) | Pins a view. | | UnpinView | [UnpinViewRequest](#unpinviewrequest) | [UnpinViewResponse](#unpinviewresponse) | Unpins a view. | ## Messages *Data models used across requests/responses.* ### CreateViewRequest | Field | Type | Label | Description | | :---- | :------------ | :---- | :---------- | | view | [View](#view) | | | ### CreateViewResponse | Field | Type | Label | Description | | :---- | :------------ | :---- | :---------- | | view | [View](#view) | | | ### DeleteViewRequest | Field | Type | Label | Description | | :------- | :----- | :---- | :---------- | | view\_id | string | | | ### DeleteViewResponse *This message has no fields.* ### GetViewRequest | Field | Type | Label | Description | | :------- | :----- | :---- | :---------- | | view\_id | string | | | ### GetViewResponse | Field | Type | Label | Description | | :---- | :------------ | :---- | :---------- | | view | [View](#view) | | | ### ListApplicableViewsRequest | Field | Type | Label | Description | | :---------- | :----- | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of views to return. The service may return fewer than this value. If unspecified, at most 50 views will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. | | page\_token | string | | A page token, received from a previous `ListApplicableViews` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListApplicableViews` must match the call that provided the page token. | | asset\_ids | string | repeated | | | run\_ids | string | repeated | | ### ListApplicableViewsResponse | Field | Type | Label | Description | | :---------------- | :------------ | :------- | :----------------------------------------------------------------------------------------------------------------------------- | | views | [View](#view) | repeated | | | next\_page\_token | string | | A token, which can be sent as `page_token` to retrieve the next page. If this field is omitted, there are no subsequent pages. | ### ListViewsRequest | Field | Type | Label | Description | | :---------- | :----- | :---- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of views to return. The service may return fewer than this value. If unspecified, at most 50 views will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000. | | page\_token | string | | A page token, received from a previous `ListViews` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListViews` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string Available fields to filter by are 'name', 'createdDate', and 'modifiedDate'. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). | ### ListViewsResponse | Field | Type | Label | Description | | :---------------- | :------------ | :------- | :----------------------------------------------------------------------------------------------------------------------------- | | views | [View](#view) | repeated | | | next\_page\_token | string | | A token, which can be sent as `page_token` to retrieve the next page. If this field is omitted, there are no subsequent pages. | ### PinViewRequest | Field | Type | Label | Description | | :------- | :----- | :---- | :---------- | | view\_id | string | | | ### PinViewResponse *This message has no fields.* ### UnpinViewRequest | Field | Type | Label | Description | | :------- | :----- | :---- | :---------- | | view\_id | string | | | ### UnpinViewResponse *This message has no fields.* ### UpdateViewRequest | Field | Type | Label | Description | | :----------- | :------------------------------------------------------ | :---- | :---------------------------- | | view | [View](#view) | | | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The list of fields to update. | ### UpdateViewResponse | Field | Type | Label | Description | | :---- | :------------ | :---- | :---------- | | view | [View](#view) | | | ### View | Field | Type | Label | Description | | :--------------------- | :---------------------------------- | :------- | :---------- | | view\_id | string | | | | name | string | | | | axis\_groups | [View.AxisGroups](#view-axisgroups) | | | | channels | [View.Channel](#view-channel) | repeated | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | is\_pinned | bool | | | ### View\.AxisGroups | Field | Type | Label | Description | | :---- | :----- | :------- | :---------- | | left | string | repeated | | | right | string | repeated | | ### View\.Channel | Field | Type | Label | Description | | :-------------------------- | :---------------------------------------------------------------------------- | :------- | :---------- | | name | string | | | | data\_type | string | | | | axis\_group | string | | | | bit\_field\_names | string | repeated | | | calculated\_channel\_config | [View.Channel.CalculatedChannelConfig](#view-channel-calculatedchannelconfig) | optional | | ### View\.Channel.CalculatedChannelConfig | Field | Type | Label | Description | | :------------------ | :-------------------------------------------------------------------------------------------------------------------------- | :------- | :---------- | | channel\_key | string | | | | channel\_references | [View.Channel.CalculatedChannelConfig.ChannelReferencesEntry](#view-channel-calculatedchannelconfig-channelreferencesentry) | repeated | | | expression | string | | | | unit | string | | | ### View\.Channel.CalculatedChannelConfig.ChannelReferencesEntry | Field | Type | Label | Description | | :---- | :----- | :---- | :---------- | | key | string | | | | value | string | | | ## Enums *Allowed constant values used in message fields.* # webhooks Source: https://docs.siftstack.com/api/reference/protocol-buffers/webhooks sift/webhooks/v1/webhooks.proto ## Services *RPC methods exposed by this API.* ### WebhookService | Method | Request | Response | Description | | :---------------------------------- | :---------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GetWebhook | [GetWebhookRequest](#getwebhookrequest) | [GetWebhookResponse](#getwebhookresponse) | Retrieve a webhook by ID. | | CreateWebhook | [CreateWebhookRequest](#createwebhookrequest) | [CreateWebhookResponse](#createwebhookresponse) | Create a webhook. | | UpdateWebhook | [UpdateWebhookRequest](#updatewebhookrequest) | [UpdateWebhookResponse](#updatewebhookresponse) | Update select fields of an existing webhook. | | ListWebhooks | [ListWebhooksRequest](#listwebhooksrequest) | [ListWebhooksResponse](#listwebhooksresponse) | Retrieve and optionally filter a list of webhooks. | | TestWebhook | [TestWebhookRequest](#testwebhookrequest) | [TestWebhookResponse](#testwebhookresponse) | Test an existing webhook or a webhook create request. This RPC will attempt to send an actual webhook with the provided parameters and forward back the response from the target. | | CreateWebhookSignatureKey | [CreateWebhookSignatureKeyRequest](#createwebhooksignaturekeyrequest) | [CreateWebhookSignatureKeyResponse](#createwebhooksignaturekeyresponse) | Create an webhook signature key. If a webhook signature key is active, the bodies of all webhooks will be signed using the signature key with HMAC-SHA-256. The signature generated will then included in the `X-Sift-Signature` HTTP header. Only one key can be held per organization. If an existing key exists, then this will simply return it. See `WebhookService_RotateWebhookSignatureKey` to rotate the key. | | GetWebhookSignatureKey | [GetWebhookSignatureKeyRequest](#getwebhooksignaturekeyrequest) | [GetWebhookSignatureKeyResponse](#getwebhooksignaturekeyresponse) | Retrieve the current webhook signature key. Will return a not found error if one doesn't yet exist. | | ToggleWebhookSignatureKeyActivation | [ToggleWebhookSignatureKeyActivationRequest](#togglewebhooksignaturekeyactivationrequest) | [ToggleWebhookSignatureKeyActivationResponse](#togglewebhooksignaturekeyactivationresponse) | Set the activation state of the organization's current webhook signature key. Will return a not found error if one doesn't yet exist. | | RotateWebhookSignatureKey | [RotateWebhookSignatureKeyRequest](#rotatewebhooksignaturekeyrequest) | [RotateWebhookSignatureKeyResponse](#rotatewebhooksignaturekeyresponse) | Generate a new webhook signature key and replace the previous one. The activation state of the new key will match the activation state of the previous. | | BatchCreateWebhookLogs | [BatchCreateWebhookLogsRequest](#batchcreatewebhooklogsrequest) | [BatchCreateWebhookLogsResponse](#batchcreatewebhooklogsresponse) | Create a batch of webhook logs. Users should not have to call this directly. | | ListWebhookLogs | [ListWebhookLogsRequest](#listwebhooklogsrequest) | [ListWebhookLogsResponse](#listwebhooklogsresponse) | Retrieve and optionally filter a list of webhook logs. | ## Messages *Data models used across requests/responses.* ### BatchCreateWebhookLogsRequest The request for a call to `WebhookService_BatchCreateWebhookLogs` to create a batch of webhook logs. | Field | Type | Label | Description | | :------- | :-------------------------------------------------- | :------- | :---------- | | requests | [CreateWebhookLogRequest](#createwebhooklogrequest) | repeated | | ### BatchCreateWebhookLogsResponse The response of a call to `WebhookService_BatchCreateWebhookResponse`. *This message has no fields.* ### CreateWebhookLogRequest Request to create a single webhook log entry. | Field | Type | Label | Description | | :--------------------- | :------------------------------------ | :------- | :---------- | | webhook\_id | string | | | | event\_id | string | | | | retry\_attempt\_number | uint32 | | | | status | [WebhookLogStatus](#webhooklogstatus) | | | | payload | string | optional | | | error\_reason | string | optional | | | sent\_date | google.protobuf.Timestamp | | | ### CreateWebhookRequest The request for a call to `WebhookService_CreateWebhook` to create a webhook. | Field | Type | Label | Description | | :------------ | :-------------------------------------- | :------- | :---------- | | name | string | | | | target\_url | string | | | | event\_type | [WebhookEventType](#webhookeventtype) | | | | payload | string | optional | | | http\_headers | [WebhookHttpHeader](#webhookhttpheader) | repeated | | ### CreateWebhookResponse The response of a call to `WebhookService_CreateWebhook`. | Field | Type | Label | Description | | :------ | :------------------ | :---- | :---------- | | webhook | [Webhook](#webhook) | | | ### CreateWebhookSignatureKeyRequest The request for a call to `WebhookService_CreateWebhookSignatureKey` to create a webhook signature key. *This message has no fields.* ### CreateWebhookSignatureKeyResponse The response for a call to `WebhookService_CreateWebhookSignatureKey`. The `active` field indicates whether or not whether the key is currently active. | Field | Type | Label | Description | | :------------- | :------------------------------------------ | :---- | :---------- | | signature\_key | [WebhookSignatureKey](#webhooksignaturekey) | | | ### GetWebhookRequest The request for a call to `WebhookService_GetWebhook` to retrieve a webhook. | Field | Type | Label | Description | | :---------- | :----- | :---- | :---------- | | webhook\_id | string | | | ### GetWebhookResponse The response of a call to `WebhookService_GetWebhook`. | Field | Type | Label | Description | | :------ | :------------------ | :---- | :---------- | | webhook | [Webhook](#webhook) | | | ### GetWebhookSignatureKeyRequest The request for a call to `WebhookService_GetWebhookSignatureKey` to retrieve the current webhook signature key. | Field | Type | Label | Description | | :--------------- | :----- | :---- | :------------------------ | | organization\_id | string | | Optional organization ID. | ### GetWebhookSignatureKeyResponse The response for a call to `WebhookService_GetWebhookSignatureKey`. The `active` field indicates whether or not whether the key is currently active. | Field | Type | Label | Description | | :------------- | :------------------------------------------ | :---- | :---------- | | signature\_key | [WebhookSignatureKey](#webhooksignaturekey) | | | ### ListWebhookLogsRequest The request for a call to `WebhookService_ListWebhookLogs` to retrieve and filter webhook logs. | Field | Type | Label | Description | | :---------- | :----- | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of webhook logs to return. The service may return fewer than this value. If unspecified, at most 50 runs will be returned. The maximum value is 1000. | | page\_token | string | | A page token, received from a previous `ListWebhookLogs` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListWebhookLogs` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. The available fields to filter by are `webhook_id`, `status`. | | order\_by | string | | How to order the retrieved webhook logs. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available field to order\_by is `created_date`. If left empty, items are ordered by `created_date` in ascending order (oldest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc" | ### ListWebhookLogsResponse The response of a call to `WebhookService_ListWebhookLogsResponse`. | Field | Type | Label | Description | | :---------------- | :------------------------ | :------- | :---------- | | logs | [WebhookLog](#webhooklog) | repeated | | | next\_page\_token | string | | | ### ListWebhooksRequest The request for a call to `WebhookService_ListWebhooks` to retrieve and filter webhooks. | Field | Type | Label | Description | | :---------- | :----- | :---- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | page\_size | uint32 | | The maximum number of webhooks to return. The service may return fewer than this value. If unspecified, at most 50 runs will be returned. The maximum value is 1000. | | page\_token | string | | A page token, received from a previous `ListWebhooks` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListWebhooks` must match the call that provided the page token. | | filter | string | | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `webhook_id`, `name`, `event_type`, `is_archived`, and `archived_date`. | | order\_by | string | | How to order the retrieved webhooks. Formatted as a comma-separated string i.e. "FIELD\_NAME\[ desc],...". Available field to order\_by is `created_date`. If left empty, items are ordered by `created_date` in ascending order (oldest-first). For more information about the format of this field, read [this](https://google.aip.dev/132#ordering) Example: "created\_date desc" | ### ListWebhooksResponse The response of a call to `WebhookService_ListWebhooks`. | Field | Type | Label | Description | | :---------------- | :------------------ | :------- | :---------- | | webhooks | [Webhook](#webhook) | repeated | | | next\_page\_token | string | | | ### RotateWebhookSignatureKeyRequest The request for a call to `WebhookService_RotateWebhookSignatureKey` replace the current webhook signature key with a new one. The activation state of the new signature key will be inherited from the previous key. If no key exists then this will return an error - see `WebhookService_CreateWebhookSignatureKey`. *This message has no fields.* ### RotateWebhookSignatureKeyResponse The response for a call to `WebhookService_RotateWebhookSignatureKey`. The `active` field indicates whether or not whether the key is currently active. | Field | Type | Label | Description | | :------------- | :------------------------------------------ | :---- | :---------- | | signature\_key | [WebhookSignatureKey](#webhooksignaturekey) | | | ### TestWebhookRequest The request for a call to `WebhookService_TestWebhook` to test an existing webhook or a webhook create request. | Field | Type | Label | Description | | :-------------------------- | :-------------------------------------------- | :---- | :---------- | | oneof form. webhook\_id | string | | | | oneof form. webhook | [Webhook](#webhook) | | | | oneof form. create\_request | [CreateWebhookRequest](#createwebhookrequest) | | | ### TestWebhookResponse The response of a call to `WebhookService_TestWebhook`. The response code and body will come from the HTTP response from the target URL. | Field | Type | Label | Description | | :------------------- | :----- | :---- | :---------- | | http\_response\_code | uint32 | | | | http\_response\_body | bytes | | | ### ToggleWebhookSignatureKeyActivationRequest The request for a call to `WebhookService_ToggleWebhookSignatureKeyActivation` to enable or disable the current webhook signature key. Set `enable` to `true` to activate the signature key, and `false` to deactivate. | Field | Type | Label | Description | | :----- | :--- | :---- | :---------- | | enable | bool | | | ### ToggleWebhookSignatureKeyActivationResponse The response for a call to `WebhookService_ToggleWebhookSignatureKeyActivation`. | Field | Type | Label | Description | | :------------- | :------------------------------------------ | :---- | :---------- | | signature\_key | [WebhookSignatureKey](#webhooksignaturekey) | | | ### UpdateWebhookRequest The request for a call to `WebhookService_UpdateWebhook` to update a webhook. | Field | Type | Label | Description | | :----------- | :------------------------------------------------------ | :---- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | webhook | [Webhook](#webhook) | | The webhook to update. The webhook's `webhook_id` field is used to identify the webhook to update and is required. | | update\_mask | [google.protobuf.FieldMask](#google-protobuf-fieldmask) | | The list of fields to be updated. The fields available to be updated are 'target\_url', 'name', 'event\_type', 'payload', 'http\_headers', 'archived\_date', 'is\_archived'. | ### UpdateWebhookResponse The response of a call to `WebhookService_UpdateWebhook`. To archive a webhook, specify `archived_date` in the `update mask` as well as a non-null value for `archived_date` in the `webhook` object. To unarchive a webhook, specify `archived_date` in the `update mask` and a `null` value for `archived_date` in the `webhook` object. | Field | Type | Label | Description | | :------ | :------------------ | :---- | :---------- | | webhook | [Webhook](#webhook) | | | ### Webhook | Field | Type | Label | Description | | :--------------------- | :-------------------------------------- | :------- | :---------- | | webhook\_id | string | | | | organization\_id | string | | | | target\_url | string | | | | name | string | | | | event\_type | [WebhookEventType](#webhookeventtype) | | | | payload | string | optional | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | archived\_date | google.protobuf.Timestamp | optional | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | | http\_headers | [WebhookHttpHeader](#webhookhttpheader) | repeated | | | is\_archived | bool | | | ### WebhookHttpHeader | Field | Type | Label | Description | | :---- | :----- | :---- | :---------- | | name | string | | | | value | string | | | ### WebhookLog | Field | Type | Label | Description | | :--------------------- | :------------------------------------ | :------- | :---------- | | webhook\_log\_id | string | | | | webhook\_id | string | | | | event\_id | string | | | | organization\_id | string | | | | status | [WebhookLogStatus](#webhooklogstatus) | | | | payload | string | optional | | | retry\_attempt\_number | uint32 | | | | error\_reason | string | optional | | | sent\_date | google.protobuf.Timestamp | | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | ### WebhookSignatureKey | Field | Type | Label | Description | | :--------------------- | :------------------------ | :---- | :---------- | | signature\_key | string | | | | active | bool | | | | created\_date | google.protobuf.Timestamp | | | | modified\_date | google.protobuf.Timestamp | | | | created\_by\_user\_id | string | | | | modified\_by\_user\_id | string | | | ## Enums *Allowed constant values used in message fields.* ### WebhookEventType | Name | Number | Description | | :------------------------------------ | :----- | :---------- | | WEBHOOK\_EVENT\_TYPE\_UNSPECIFIED | 0 | | | WEBHOOK\_EVENT\_TYPE\_RULE\_VIOLATION | 1 | | ### WebhookLogStatus | Name | Number | Description | | :-------------------------------- | :----- | :---------- | | WEBHOOK\_LOG\_STATUS\_UNSPECIFIED | 0 | | | WEBHOOK\_LOG\_STATUS\_SENT | 1 | | | WEBHOOK\_LOG\_STATUS\_FAILED | 2 | | | WEBHOOK\_LOG\_STATUS\_RETRYING | 3 | | # Create, preview, and evaluate Rules programmatically Source: https://docs.siftstack.com/api/review/evaluate-rules Create, preview, and evaluate Rules programmatically against a Run or Asset to generate a Report and Annotations. After completing this workflow, you can create Rules programmatically and evaluate them against a Run or Assets with a time range to generate a Report containing the resulting Annotations. You can also preview the evaluation first to confirm the result before committing to it. ## Before you begin * You have [a Sift API key and your base URLs](/documentation/manage/set-up-api-access). * You have either the ID of the Run to evaluate Rules against, or the IDs of the Assets and the time range to evaluate Rules over. ## How Rule creation, preview, and evaluation work You create Rules using the `BatchUpdateRules` endpoint, then evaluate them using `EvaluateRulesPreview` or `EvaluateRules` from the Rule Evaluation Service. Rules created programmatically appear in the Rules tab and are editable through the UI or the API. Each evaluation request specifies exactly one time option (a Run, or Assets with a time range) and exactly one mode option (current Rule versions, specific Rule versions, or a Report Template). **Other clients**: You can also create and evaluate Rules using the official [Python](/api/reference/protocol-buffers#python), [Go](/api/reference/protocol-buffers#go), or [Rust](/api/reference/protocol-buffers#rust) client, or generate a client for another language with [Buf](/api/clients/generate-a-client-with-buf), since all of them use the same Protocol Buffers that back the REST API. ## Create a Rule Call the [`BatchUpdateRules`](/api-reference/ruleservice/batchupdaterules) endpoint to create a Rule programmatically. Use `assetConfiguration` to scope the Rule to the Asset whose Channels the condition references. ```bash curl theme={null} curl -X PUT -H "Authorization: Bearer $API_TOKEN" -H "Content-Type: application/json" $SIFT_REST_URL/api/v1/rules:batchUpdate -d '{ "rules": [ { "name": "YOUR_RULE_NAME", "description": "YOUR_RULE_DESCRIPTION", "assetConfiguration": { "assetIds": ["YOUR_ASSET_ID"] }, "conditions": [ { "expression": { "calculatedChannel": { "expression": "$1 > 100", "channelReferences": { "$1": { "name": "YOUR_CHANNEL_NAME" } } } }, "actions": [ { "actionType": "ANNOTATION", "configuration": { "annotation": { "annotationType": "ANNOTATION_TYPE_DATA_REVIEW" } } } ] } ] } ], "overrideExpressionValidation": false }' ``` ```python Python theme={null} # To run these examples, install the client: pip install sift-stack-py # These examples are written for sift-stack-py v0.19.1 import os from dotenv import load_dotenv from sift_client import SiftClient from sift_client.sift_types.channel import ChannelReference from sift_client.sift_types.rule import RuleAction, RuleActionType, RuleAnnotationType, RuleCreate load_dotenv() client = SiftClient( api_key=os.getenv("SIFT_API_KEY"), grpc_url=os.getenv("SIFT_GRPC_URI"), rest_url=os.getenv("SIFT_REST_URI"), ) rule = client.rules.create( RuleCreate( name="YOUR_RULE_NAME", description="YOUR_RULE_DESCRIPTION", asset_ids=["YOUR_ASSET_ID"], expression="$1 > 100", channel_references=[ ChannelReference(channel_reference="$1", channel_identifier="YOUR_CHANNEL_NAME"), ], action=RuleAction( action_type=RuleActionType.ANNOTATION, annotation_type=RuleAnnotationType.DATA_REVIEW, ), ) ) print(rule) ``` **annotationType**: * `ANNOTATION_TYPE_DATA_REVIEW` creates an issue-tracking Annotation with a [status](/documentation/reference/annotations-reference#statuses) workflow, the right choice for most Rule actions like this one. It can be assigned to a user, and starts as **Open** by default until someone marks it **Failed** or **Accepted** during review. * `ANNOTATION_TYPE_PHASE` creates an informational milestone marker with no status instead, and won't behave the same way for a condition like this. ## Preview a Rule evaluation Call the [`EvaluateRulesPreview`](/api-reference/ruleevaluationservice/evaluaterulespreview) endpoint to see what Annotations it would generate, without creating a Report or saving any Annotations. Use the Rule ID from the previous step, or any existing Rule you want to evaluate. ```bash curl theme={null} curl -X POST -H "Authorization: Bearer $API_TOKEN" -H "Content-Type: application/json" $SIFT_REST_URL/api/v1/rules/evaluate-rules:preview -d '{ "run": { "id": "RUN_ID" }, "rules": { "rules": { "ids": { "ids": ["RULE_ID"] } } } }' ``` **Ingestion ordering**: If you create a Run, stream Channel data to it, and immediately call `EvaluateRulesPreview`, the preview can run before the streamed data finishes processing, causing a "no matching Channels found for Rule" error. To guarantee the Channels are available before evaluation, use a [data import](/documentation/ingest/data-import/import-data-from-a-file) instead of streaming. The Channels are available once the import completes. **Preview timeout handling**: [`EvaluateRulesPreview`](/api-reference/ruleevaluationservice/evaluaterulespreview) has a 60-second execution limit and can time out on long Runs with high-rate Channels. If it times out, create the Rule and call [`EvaluateRules`](/api-reference/ruleevaluationservice/evaluaterules) against the full Run instead of relying on preview to validate it first. **Python**: Unlike the Create and Evaluate steps, the official Python client doesn't yet have a method to preview a Rule evaluation. Support is coming soon. ## Evaluate Rules against a run Call the [`EvaluateRules`](/api-reference/ruleevaluationservice/evaluaterules) endpoint with a Run ID and the Rule IDs from the previous steps, or any existing Rule you want to evaluate. ```bash curl theme={null} curl -X POST -H "Authorization: Bearer $API_TOKEN" -H "Content-Type: application/json" $SIFT_REST_URL/api/v1/rules/evaluate-rules -d '{ "run": { "id": "RUN_ID" }, "rules": { "rules": { "ids": { "ids": ["RULE_ID"] } } }, "reportName": "REPORT_NAME" }' ``` ```python Python theme={null} # To run these examples, install the client: pip install sift-stack-py # These examples are written for sift-stack-py v0.19.1 import os from dotenv import load_dotenv from sift_client import SiftClient load_dotenv() client = SiftClient( api_key=os.getenv("SIFT_API_KEY"), grpc_url=os.getenv("SIFT_GRPC_URI"), rest_url=os.getenv("SIFT_REST_URI"), ) job = client.reports.create_from_rules( name="REPORT_NAME", run="RUN_ID", rules=["RULE_ID"], ) report = client.reports.wait_until_complete(job=job) print(report) ``` **Asynchronous processing**: It's common for `EvaluateRules` to return a `jobId`, even when `reportId` is already set. This means the evaluation is still processing and `createdAnnotationCount` in this response isn't final yet. Poll [`ListJobs`](/api-reference/jobservice/listjobs) with a `job_id` filter until the job completes to get the actual count. ## Verify # Create, preview, and evaluate Ad Hoc Rules Source: https://docs.siftstack.com/api/review/manage-ad-hoc-rules Create, preview, and evaluate Ad Hoc Rules programmatically for automated pipelines such as CI/CD. After completing this workflow, you can use the API to create, preview, and evaluate an Ad Hoc Rule for automated workflows, such as CI/CD pipelines, and generate a Report and Annotations. ## Before you begin * You have [a Sift API key and your base URLs](/documentation/manage/set-up-api-access). * You have either the ID of the Run to evaluate the Ad Hoc Rule against, or the IDs of the Assets and the time range to evaluate it over. ## How Ad Hoc Rules differ from Rules An Ad Hoc Rule is a Rule intended for automated workflows such as CI/CD pipelines, where you create and evaluate the Rule in a single pipeline step. * Setting `isExternal` to `true` when you create a Rule marks it as an Ad Hoc Rule instead of a Rule managed through the UI. * Ad Hoc Rules don't appear in the Rules tab, unlike Rules that aren't Ad Hoc. * Because of that, any Report generated from an Ad Hoc Rule displays the Rule's logic directly, so reviewers can see what was evaluated without looking it up elsewhere. * Ad Hoc Rules are always immutable once created, since they're meant to be defined externally in source control and re-applied through your pipeline rather than edited in place. Rules that aren't Ad Hoc stay editable. See [Rules vs Ad Hoc Rules](/documentation/reference/rule-settings#rules-vs-ad-hoc-rules) for the full comparison and when to use each. ## How Ad Hoc Rule creation, preview, and evaluation work You create an Ad Hoc Rule using the `BatchUpdateRules` endpoint with `isExternal` set to `true`, then preview or evaluate it using `EvaluateRulesPreview` or `EvaluateRules` from the Rule Evaluation Service, the same endpoints used for Rules. **Other clients**: You can also create and evaluate Ad Hoc Rules using the official [Python](/api/reference/protocol-buffers#python), [Go](/api/reference/protocol-buffers#go), or [Rust](/api/reference/protocol-buffers#rust) client, or generate a client for another language with [Buf](/api/clients/generate-a-client-with-buf), since all of them use the same Protocol Buffers that back the REST API. ## Create an Ad Hoc Rule Call the [`BatchUpdateRules`](/api-reference/ruleservice/batchupdaterules) endpoint with `isExternal` set to `true`. Use `assetConfiguration` to scope the Rule to the Asset whose Channels the condition references. ```bash curl theme={null} curl -X PUT -H "Authorization: Bearer $API_TOKEN" -H "Content-Type: application/json" $SIFT_REST_URL/api/v1/rules:batchUpdate -d '{ "rules": [ { "name": "YOUR_AD_HOC_RULE_NAME", "description": "YOUR_AD_HOC_RULE_DESCRIPTION", "isExternal": true, "assetConfiguration": { "assetIds": ["YOUR_ASSET_ID"] }, "conditions": [ { "expression": { "calculatedChannel": { "expression": "$1 > 100", "channelReferences": { "$1": { "name": "YOUR_CHANNEL_NAME" } } } }, "actions": [ { "actionType": "ANNOTATION", "configuration": { "annotation": { "annotationType": "ANNOTATION_TYPE_DATA_REVIEW" } } } ] } ] } ], "overrideExpressionValidation": false }' ``` ```python Python theme={null} # To run these examples, install the client: pip install sift-stack-py # These examples are written for sift-stack-py v0.19.1 import os from dotenv import load_dotenv from sift_client import SiftClient from sift_client.sift_types.channel import ChannelReference from sift_client.sift_types.rule import RuleAction, RuleActionType, RuleAnnotationType, RuleCreate load_dotenv() client = SiftClient( api_key=os.getenv("SIFT_API_KEY"), grpc_url=os.getenv("SIFT_GRPC_URI"), rest_url=os.getenv("SIFT_REST_URI"), ) rule = client.rules.create( RuleCreate( name="YOUR_AD_HOC_RULE_NAME", description="YOUR_AD_HOC_RULE_DESCRIPTION", is_external=True, asset_ids=["YOUR_ASSET_ID"], expression="$1 > 100", channel_references=[ ChannelReference(channel_reference="$1", channel_identifier="YOUR_CHANNEL_NAME"), ], action=RuleAction( action_type=RuleActionType.ANNOTATION, annotation_type=RuleAnnotationType.DATA_REVIEW, ), ) ) print(rule) ``` **annotationType**: * `ANNOTATION_TYPE_DATA_REVIEW` creates an issue-tracking Annotation with a [status](/documentation/reference/annotations-reference#statuses) workflow, the right choice for most Rule actions like this one. It can be assigned to a user, and starts as **Open** by default until someone marks it **Failed** or **Accepted** during review. * `ANNOTATION_TYPE_PHASE` creates an informational milestone marker with no status instead, and won't behave the same way for a condition like this. ## Preview an Ad Hoc Rule Call the [`EvaluateRulesPreview`](/api-reference/ruleevaluationservice/evaluaterulespreview) endpoint to see what Annotations it would generate, without creating a Report or saving any Annotations. Use the Rule ID from the previous step. ```bash curl theme={null} curl -X POST -H "Authorization: Bearer $API_TOKEN" -H "Content-Type: application/json" $SIFT_REST_URL/api/v1/rules/evaluate-rules:preview -d '{ "run": { "id": "RUN_ID" }, "rules": { "rules": { "ids": { "ids": ["RULE_ID"] } } } }' ``` **Ingestion ordering**: If you create a Run, stream Channel data to it, and immediately call `EvaluateRulesPreview`, the preview can run before the streamed data finishes processing, causing a "no matching Channels found for Rule" error. To guarantee the Channels are available before evaluation, use a [data import](/documentation/ingest/data-import/import-data-from-a-file) instead of streaming. The Channels are available once the import completes. **Preview timeout handling**: [`EvaluateRulesPreview`](/api-reference/ruleevaluationservice/evaluaterulespreview) has a 60-second execution limit and can time out on long Runs with high-rate Channels. If it times out, create the Ad Hoc Rule and call [`EvaluateRules`](/api-reference/ruleevaluationservice/evaluaterules) against the full Run instead of relying on preview to validate it first. **Python**: Unlike the Create and Evaluate steps, the official Python client doesn't yet have a method to preview an Ad Hoc Rule evaluation. Support is coming soon. ## Evaluate an Ad Hoc Rule Call the [`EvaluateRules`](/api-reference/ruleevaluationservice/evaluaterules) endpoint with a Run ID and the Rule ID from the previous step. ```bash curl theme={null} curl -X POST -H "Authorization: Bearer $API_TOKEN" -H "Content-Type: application/json" $SIFT_REST_URL/api/v1/rules/evaluate-rules -d '{ "run": { "id": "RUN_ID" }, "rules": { "rules": { "ids": { "ids": ["RULE_ID"] } } }, "reportName": "REPORT_NAME" }' ``` ```python Python theme={null} # To run these examples, install the client: pip install sift-stack-py # These examples are written for sift-stack-py v0.19.1 import os from dotenv import load_dotenv from sift_client import SiftClient load_dotenv() client = SiftClient( api_key=os.getenv("SIFT_API_KEY"), grpc_url=os.getenv("SIFT_GRPC_URI"), rest_url=os.getenv("SIFT_REST_URI"), ) job = client.reports.create_from_rules( name="REPORT_NAME", run="RUN_ID", rules=["RULE_ID"], ) report = client.reports.wait_until_complete(job=job) print(report) ``` **Asynchronous processing**: It's common for `EvaluateRules` to return a `jobId`, even when `reportId` is already set. This means the evaluation is still processing and `createdAnnotationCount` in this response isn't final yet. Poll [`ListJobs`](/api-reference/jobservice/listjobs) with a `job_id` filter until the job completes to get the actual count. ## Verify # Changelog Source: https://docs.siftstack.com/changelog Record of all notable updates made to Sift ### Default sampling method * "Min/Max" now replaces "LTTB" as the default sampling method. ### Calculated Channels (CCs) as Channel inputs to CC expressions * Calculated Channels can now reference other Calculated Channels as Channel inputs in their expressions, providing a consistent mechanism for defining derived signals and improving the reusability and organization of complex analytical logic. ### Live Mode improvements * Improved overall Live Mode performance for smoother real-time analysis * Fixed flickering that some users experienced during streaming * Enabled Zoom X in Live Mode for Timeseries Panels * Resolved issues that caused data to intermittently drop out or disappear ### Table Panel enhancements * Added the ability to filter directly from Table Panel column headers * Improved default column widths to better fit content * Made manual column resizing easier and more predictable * Introduced alternating row shading for improved readability on large tables ### Chart interaction improvements * Added support for panning and zooming along the Y-axis for finer signal inspection ### Time controls and Sync Time * Simplified time-range controls for clearer workflows * Moved the global time picker under Sync Time to unify cross-Panel time coordination * Added quick access to time-range presets (for example, Last 5 minutes) in Sync Time * Fixed bugs that previously caused Panels to fall out of sync when using shared time ranges ### Open Explore v1 directly from Grafana Users can now open Explore v1 directly from Grafana and specify exactly what they want to analyze, including which Channels and Calculated Channels to plot and which Asset and Run to display. This update makes it easier to pivot from Grafana dashboards into detailed historical analysis and root-cause investigation within Sift. [Learn more](https://github.com/sift-stack/sift-grafana-datasource/releases/tag/v1.3.0). ### Easily recreate and share visual analyses Panel Configurations (Beta) build on and expand the capabilities previously offered by Views in Explore v1, providing more granular control, greater flexibility, and improved reusability across analysis workflows. They let you capture and reuse the complete visualization setup of an individual Panel, including Channel selections, axis mappings, color scales, hidden states, and styling preferences. A configuration can be applied to one Panel at a time on new Runs or other Assets for consistent and repeatable analysis. Configurations can also be edited and shared to support collaborative team workflows. When applying a configuration, you can choose whether it affects a single data source or all sources. [Learn more](./documentation/reference/explore-settings). ### Bug fixes and minor improvements * Fixed flickering issues in Explore v2 (Beta) Live Mode. * Moved the workspace-level time range picker under the “Sync Panels” option in Explore v2 (Beta) and resolved an issue where it could become stuck in an invalid state (for example, "last 30 seconds"). * Updated y-axis autoscaling to support viewing Channels from two different Assets in a single Run. * You can now remove plotted Table columns in Explore v2 (Beta) using the right-click context menu. * Resolved Share Link generation issues in Explore v1. * Fixed a bug where plotting Channels collapsed the Channel selector Tree view in Explore v2 (Beta). ### Bug fixes and minor improvements in progress * Improving the smoothness of data rendering in Explore v2 (Beta) Live Mode. * Enhancing Explore v2 (Beta) Table panel display and filtering. * Fixing additional bugs around Sync Panels mode in Explore v2 (Beta). # Align Runs for comparison Source: https://docs.siftstack.com/documentation/analyze/align-runs-comparison Align multiple Runs to a shared T-0 reference point so signals line up for meaningful comparison. After completing this topic, you can align multiple Runs with a common reference point to compare signals across Runs on a shared timeline. ## Before you begin * You have at least two Runs plotted in the same Panel in [Explore](/documentation/reference/explore-settings). ## How Run alignment works Runs rarely start at the same absolute time, so plotting them together without alignment results in signals that appear offset. Alignment solves this by defining a shared T-0 reference point for each Run, converting absolute timestamps to relative time so signals line up for direct comparison. You can align Runs to a Run start, Run end, a specific timestamp, or an Annotation. For supported alignment methods, see [Time alignment](/documentation/reference/explore-settings#time-alignment). ## Create a relative time alignment 1. In an **Explore** Panel with at least two [Runs](/documentation/ingest/data-import/import-data-from-a-file) plotted, click **Settings**. 2. Open the **Time-alignment** tab. 3. In the **Alignment** list, select **Create relative alignment**. 4. In the **Name** box, enter a name for the alignment. 5. In the **Default alignment method** list, select a method. 6. Optional: Configure how the alignment is applied: * To apply the alignment method to all Runs, click **Apply default to all**. * To configure an individual Run, select a method from the **Alignment method** list in the Run's tile under **Alignment points**. 7. Optional: Configure additional settings if you selected **Timestamp** or **Annotation** as the method. ## Align to an event using an Annotation To align Runs to an Annotation, each Run needs a matching Annotation marking the event before you can select it as an alignment point. Add the Annotation using one of the following methods: * **Rule-based**: Create a [Rule](/documentation/review/detect-deviations-automatically-using-rules) whose expression detects the event, then evaluate the Rule against each Run you want to align. An Annotation is not created until the Rule has been evaluated against that Run's data. * **Manual**: Add an Annotation directly on a Run in Explore, without a Rule. Use this for a one-off alignment that doesn't need to repeat across future Runs. Once each Run has the Annotation, select **Annotation** as the alignment method and point it at that Annotation's start or end. All Runs then share a common relative T-0 anchored to the event. ## Reference * [Explore settings](/documentation/reference/explore-settings) # Analyze a Run Source: https://docs.siftstack.com/documentation/analyze/analyze-a-run Open a Run in Explore, plot Channels, build a multi-Panel workspace to analyze and share telemetry. After completing this topic, you can visualize and explore telemetry from a single Run to understand signal behavior over time, then share your findings with your team. ## Before you begin * You have a Run with ingested telemetry data. * You know which Channels you want to investigate. ## How Run analysis works A Run represents a defined time window of telemetry captured from an Asset. To analyze a Run, you open it in [Explore](/documentation/reference/explore-settings) and plot Channels across Panels to visualize signal behavior over time. Explore supports multiple [Panel types](/documentation/reference/explore-settings#panel-types), each suited to a different kind of analysis. For enum and boolean channels, use the [Enum Panel](/documentation/reference/explore-settings#panel-types) to visualize discrete states as a color-coded timeline. You can arrange multiple Panels side by side and save your layout as a [Panel Configuration](/documentation/reference/explore-settings#panel-configurations) for reuse across future Runs. **Phase Annotation**: If a Run spans multiple tests or sub-events, mark the start and end of each one with a [Phase Annotation](/documentation/reference/explore-settings#annotations). Phase Annotations let you correlate telemetry to a specific test without creating a separate Run for each one, and you can use them as alignment points when comparing the same test across Runs. ## Open and analyze a Run 1. Select **Runs** in the navigation, then enter the Run name in the **Search** box. 2. In the **Runs** table, click the **Run** you want to analyze. 3. Click **Explore**. 4. Select a [Panel type](/documentation/reference/explore-settings#panel-types) to add to the workspace. 5. In the **Channels** tab, click or drag a Channel onto the Panel to plot it. * To plot multiple Channels at once, hold **Shift** and click to select a range, or hold **Cmd** (Mac) / **Ctrl** (Windows, Linux) and click to add or remove individual Channels. Drag any selected Channel to plot the entire selection, or right-click any selected Channel to apply a context menu action to all selected Channels. 6. Optional: To change how Channel data is downsampled, open the Panel settings, click the **Channel** tab, locate the Channel, click **Expand**, and select a method from the **Sampling method** list. * See [Sampling method options](/documentation/reference/explore-settings#timeseries-channel) for available methods. 7. Optional: To compare signals side by side, [split](/documentation/reference/explore-settings#layout) a Panel by right-clicking its tab and selecting a split direction. * The split duplicates the Panel in the selected direction and creates an independent Panel that can be configured separately. * Alternatively, click to add a new Panel from scratch. 8. Optional: Use [range controls](/documentation/reference/explore-settings#range-controls) to zoom into a time range and focus on a specific event or anomaly. 9. Optional: To create a new Run or Metrics Panel from a specific X-axis range in a Time Series Panel, click **Select X** in the toolbar, click and drag over the desired range, right-click the selection, and select **Create Run** or **Create Metrics Panel**. * See [Run from selection](/documentation/reference/explore-settings#run-from-selection) and [Metrics Panel from selection](/documentation/reference/explore-settings#metrics-panel-from-selection) for details. ## Set a Panel's timezone Every new Panel uses a default timezone. To change the default for all new Panels, open **User Settings** in Explore and select a different **Default Timezone**. To display a different timezone on a single Panel without changing that default, set it directly on the Panel. 1. In the Panel, click **Settings**. 2. Open the **Time-alignment** tab. 3. In the **Alignment** list, select **Timezone**. 4. Select the timezone you want to apply to this Panel. **Supported Panels**: Timeseries, Histogram, Geo Map, FFT, and Scatter Plot Panels support a per-Panel timezone override. ## Share your analysis Instead of describing what you found, send a teammate a link to it. Sift captures the current workspace state, including plotted Channels, panel layout, and time range, and generates a link that opens the same view. 1. Click **Share**. 2. Share the link with your team. ## Reference * [Explore settings](/documentation/reference/explore-settings) # Compare a Run against a baseline Source: https://docs.siftstack.com/documentation/analyze/compare-run-baseline Compare a new Run against a baseline Run to identify regressions and validate expected behavior. After completing this topic, you can compare a new Run against a baseline Run in [Explore](/documentation/reference/explore-settings) to identify regressions and validate that signal behavior falls within the expected range. ## Before you begin * You have a new Run with ingested telemetry data that you want to evaluate. * You have at least one historical Run that represents expected behavior to use as a baseline. ## How baseline comparison works In Explore, you can load a historical Run as your baseline and plot a new Run alongside it. By plotting the same Channels across both Runs, you can visually compare signal behavior and quickly identify where the new Run diverges from expected behavior. To compare a new Run against a group of historical Runs on a shared aligned time axis rather than a single baseline, use Families. See [Compare Runs visually against a Family baseline](/documentation/analyze/families/compare-runs-visually-against-a-family-baseline). ## Compare a Run to a baseline 1. Select **Runs** in the navigation, then enter the name of the historical Run you want to use as the baseline in the **Search** box. 2. In the **Runs** table, click the Run. 3. Click **Explore**. 4. Select a [Panel type](/documentation/reference/explore-settings#panel-types) to add to the workspace. 5. In the **Channels** tab, click or drag a Channel onto the Panel to plot it. 6. Click **Select data** to add the new Run you want to compare. 7. Plot the same Channel from the new Run to compare it directly against the baseline. 8. Optional: Open the **Time-Alignment** tab in the Panel settings to [customize the alignment configuration](/documentation/reference/explore-settings#time-alignment) for all plotted Runs. * The Time-Alignment tab is available in the Timeseries, Histogram, Geo Map, FFT, and Scatter Plot Panels. 9. Optional: Click **Time Range** in the toolbar to align all Panels to the same time range. * In the **Synced Panel Time** dialog, select **Absolute** to set a specific time range or **Relative** to align to T-0, then click **Sync All**. 10. Optional: Use [range controls](/documentation/reference/explore-settings#range-controls) to zoom into a time range and focus on a specific divergence. ## Reference * [Explore settings](/documentation/reference/explore-settings) # Compare signals over time Source: https://docs.siftstack.com/documentation/analyze/compare-signals-over-time Plot multiple Channels in the same workspace to identify correlations, trends, and dependencies between signals. After completing this workflow, you can plot multiple Channels together in Explore, overlaid or side by side, to understand how signals relate to each other over time. ## Before you begin * You have a [Run](/documentation/ingest/data-import/import-data-from-a-file) with ingested telemetry data. * You know which Channels you want to compare. ## How signal comparison works Plotting multiple Channels together lets you see how signals behave relative to each other over the same time range. There are two ways to compare signals, each suited to a different kind of analysis: * **Overlay in the same Panel** to directly compare signals on a shared axis. Use this when you want to spot correlations, timing differences, or dependencies between signals with similar scales. * **Split into adjacent Panels** to compare signals with different scales or units side by side without overlapping them. Use this when visual separation makes the comparison clearer. ## Compare signals 1. Select **Runs** in the navigation, then enter the Run name in the **Search** box. 2. In the **Runs** table, click the **Run** you want to analyze. 3. Click **Explore**. 4. Select a [Panel type](/documentation/reference/explore-settings#panel-types) to add to the workspace. 5. In the **Channels** tab, click or drag a Channel onto the Panel to plot it. 6. Add additional Channels depending on how you want to compare them: * To overlay signals, add one or more related Channels to the same Panel. * To compare side by side, [split](/documentation/reference/explore-settings#layout) the Panel by right-clicking its tab and selecting a split direction. * The split duplicates the Panel and creates an independent Panel that can be configured separately. Alternatively, click to add a new Panel from scratch. * To work with multiple Channels at once, use multi-select: **Shift+click** to select a range of Channels, or **Cmd+click** (Mac) / **Ctrl+click** (Windows, Linux) to add or remove individual Channels from the selection. Drag any selected Channel to move the entire selection together, or right-click any selected Channel to apply a context menu action to all selected Channels. 7. Optional: To move a Channel to a different axis, click and drag the Channel entry in the Timeseries Panel legend and select the target axis. * See [Axis assignment](/documentation/reference/explore-settings#axis-assignment) for supported axes. 8. Optional: To apply axis and style settings to all Channels at once, open the Panel settings, click the **Channel** tab, select **All Channels** from the **Group by** list, and configure the settings. Available in Timeseries and FFT Panels. * See [Bulk axis and style assignment](/documentation/reference/explore-settings#bulk-axis-and-style-assignment). 9. Optional: Click **Time Range** in the toolbar to align all Panels to the same time range. * In the **Synced Panel Time** dialog, select **Absolute** to set a specific time range or **Relative** to align to T-0, then click **Sync All**. 10. Optional: To analyze Channels with different scales independently, open the Timeseries Panel settings, go to the **General** tab, and turn on the **Split by Y-Axis** toggle. 11. Optional: Use [range controls](/documentation/reference/explore-settings#range-controls) to zoom into a time range and focus on a specific period of interest. ## Compare the same Channel across multiple Runs When you load multiple Runs into Explore, each Channel appears separately for each Run. Overlay same-name Channels to compare a signal's behavior across test sessions, then collapse the legend to keep the chart readable. 1. Add two or more Runs as data sources in Explore. 2. In the **Channels** tab, right-click the Channel you want to compare across Runs. 3. Select **Plot all with matching name**. Sift plots every instance of that Channel name across all loaded Runs in the same Panel. 4. To merge the per-Run legend entries into one, right-click any Channel entry in the Timeseries Panel legend, select **Collapse by**, then choose an option. **Plot all with matching name** matches on the exact Channel name. If the Channel is a bit in a bitfield, this option can add an incorrect Channel. Use [Families](/documentation/analyze/families/overview) for bitfield Channels or for richer cross-Run analysis such as baselines and deviation detection. ## Reference * [Explore settings](/documentation/reference/explore-settings) # Compare Runs visually against a Family baseline Source: https://docs.siftstack.com/documentation/analyze/families/compare-runs-visually-against-a-family-baseline Overlay Family members on a shared aligned time axis in Explore to inspect variance, identify outliers, and compare a new Run against the historical spread. After completing this topic, you can plot all Family members in Explore on a common aligned time axis and compare a new Run directly against the historical baseline. New to Families? Read the [Overview](/documentation/analyze/families/overview) to understand how members, alignments, and statistics work together before proceeding. ## When to use this workflow Use this workflow when you want to: * Visually inspect how consistently a signal behaves across a group of historical Runs * Identify outlier Runs before deciding whether to include or exclude them from the Family * Compare a new Run's signal shape against the historical spread before running Rules This workflow is typically the first step after creating a Family and a natural complement to running Family Rules. ## Before you begin * You have a Family with at least two included members and at least one alignment configured. See [Group Runs into a Family](/documentation/analyze/families/group-runs-into-a-family). ## Complete the workflow ### Step 1: Open the Family in Explore 1. In the Sift navigation panel, click **Families**. 2. Click the name of the Family to open its overview page. 3. Click **Explore Family**. Sift opens Explore with all included Family members preloaded as data sources. Excluded Runs do not appear and cannot be plotted. If you already have an Explore session open, add the Family by clicking **Select data** in the data selector panel and selecting the Family. This loads all included members into the existing session. Hover over the Family in the data source panel to see the count of candidate Runs awaiting review. Click **Review Run(s)** to inspect them in Explore before deciding whether to include or exclude them. ### Step 2: Plot Channels In the **Channels** tab: 1. Expand a Family member to browse its channels. 2. Click a channel name to plot it, or drag it onto a panel. 3. To plot the same channel from all members at once, right-click the channel name and choose **Plot all with matching name**. Channels with the same name from different members are plotted together so you can inspect variance across the group at a glance. ### Step 3: Set the alignment Alignment controls the T-0 reference point that synchronizes all members on the time axis. For a Time Series Panel, use the **X-axis** control at the bottom of the panel (**Time in UTC**) to switch between the alignments defined on the Family, or open the **Time-Alignment** tab in panel settings. You can only select from alignments already defined on the Family. You cannot override them in Explore. Switching to a different alignment immediately re-syncs all members to the new T-0. Any new panel you add to the session inherits the active alignment mode automatically. ### Step 4: Add a new Run for comparison To compare a Run that is not a Family member against the baseline: 1. Click **Compare settings** on the panel toolbar. 2. Select the Run you want to compare from the data source dropdown. Select both the Family and the candidate Run to view: * If you have a Family open in Explore, click **Select data**, in **Select telemetry source** select **Runs**, select a Run, and then click **Update**. * If you are starting a new exploration, in Explore, click **Select data**, in **Select telemetry source**, select a Run and select a Family, and then click **Update**. When viewing the Family's alignments, the candidate Run automatically inherits the Family's alignment method and you can continue to plot channels from both the Family and Run. If the Run is unable to resolve against the Family's alignment method, go to Panel settings, select the **Time-Alignment** tab, and manually set the Run's alignment method. The new Run inherits the panel's active alignment automatically and aligns with the Family members without any additional configuration. When you add a non-Family Run, Sift resolves its T-0 using the same alignment type defined on the Family; if the Run does not contain the alignment event, Sift falls back to Run start. Differences from the historical spread are immediately visible. ### Step 5: Create or update a Family from a session If an Explore session contains the Runs you want to group, you can create a Family or add Runs to an existing one without leaving Explore. **To create a new Family from the session**: 1. Click **Create Family from Session** in the session options. 2. Name the Family and configure the initial alignment. 3. Click **Create**. **To add session Runs to an existing Family**: 1. Click **Update Family from Session** in the session toolbar. 2. Select the target Family. 3. Choose which session Runs to add as candidates or members. 4. Click **Save**. ### Step 6: Reduce visual noise When many overlapping channels make the chart hard to read: * **Hover** over a channel name in the legend to highlight it and dim all others. * **Right-click** a channel in the legend to isolate it and hide all others. Right-click again to restore the full view. To distinguish the Family from the new Run in the legend: * Enable **Show family name** in **Channel settings** to prefix each channel label with the Family name. * Enable **Group by family** to group the legend by Family rather than by Run. * In the legend settings, choose **Collapse to one** and assign the Family a single color so the new Run you added for comparison stands out clearly against the baseline. ## Verify the result After completing this workflow: * All included Family members are plotted on a shared aligned time axis. * Switching alignments re-syncs all members immediately. * Any new Run you added is overlaid against the historical spread using the same T-0 reference. ## Next steps * To compute aggregate statistics and write Rules that automatically flag deviations, see [Detect statistical deviations using Family Rules](/documentation/analyze/families/detect-deviations-from-a-historical-baseline). * To add or remove members based on what you observed in Explore, see [Manage Families](/documentation/analyze/families/keep-a-family-current). # Detect statistical deviations using Family Rules Source: https://docs.siftstack.com/documentation/analyze/families/detect-deviations-from-a-historical-baseline Automatically flag when new data falls outside the expected range of your historical reference. After completing this topic, you can configure Family statistics, write a Rule that uses those statistics as dynamic thresholds, and view flagged deviations in a Report. New to Families? Read the [Overview](/documentation/analyze/families/overview) to understand how members, alignments, statistics, and Rules work together before proceeding. ## When to use this workflow Use this workflow when a fixed threshold is not the right approach for your telemetry. Instead of checking whether a channel exceeds a hardcoded limit, a Family Rule checks whether a new Run falls outside the statistical envelope of your reference Runs. For example, more than 2 standard deviations from the mean of all known-good acceptance tests. Common use cases: * **Acceptance testing**: flag Runs that fall outside mean ± Nσ of a known-good baseline * **Regression detection**: flag simulation builds whose output diverges from a reference signal shape ## Before you begin * A Family with at least two included members and at least one alignment configured. See [Group Runs into a Family](/documentation/analyze/families/group-runs-into-a-family). * Permission to create Rules (Admin or Editor role). ## Complete the workflow ### Step 1: Configure Family statistics Family statistics compute aggregate time series across all included members. You need at least one statistic before you can write a Family Rule. **How computation works**: Sift produces each statistic through a fixed pipeline: 1. First, each Run is normalized to a common time axis using the alignment you configured. 2. Then a dynamic window scopes the comparison to the phase of interest. Bucketing normalizes all occurrences to a single value per bucket regardless of underlying sample rate, so each Run contributes equally. 3. Finally, the selected aggregation is computed per bucket across all contributing occurrences. The **output rate** controls bucket width: a lower rate smooths noise before aggregation, and a higher rate preserves temporal detail. **Data ranges** scope the computation to a specific test phase rather than the full Run duration. For a full explanation, see [Families reference](/documentation/reference/families-reference). From the Family overview page, click **Create Family Stat** in the **Family Analysis** section and fill in the following fields. **Aggregate Channel Group**: Select the channel to aggregate. Sift searches all included members for a channel matching that name. If some Runs use a different name for the same measurement, click **Customize** to define fallback channel names that are tried in order. Runs with no match across the primary name and all fallbacks are excluded from that statistic. **Aggregation type**: How to aggregate across Runs at each time step. For a sigma-band Rule, create two statistics on the same channel: one `Average` and one `Standard Deviation`. For an envelope Rule, create `Minimum` and `Maximum`. **Output data rate**: The sample rate of the output in Hz. The default is 1 Hz. **Data ranges** (optional): The time window within each Run used for the computation. By default, the full Run is used. To scope the computation to a specific phase of the test, click **Add range** and define a dynamic window: 1. Set the **T-0 alignment** that anchors the window. 2. Set **window start** and **window end** as offsets from T-0; for example, `-10s` to `+30s` captures a 40-second window centered on the event. Click **Preview** to verify the aggregate looks correct before saving, then click **Save**. Repeat for each statistic you need. A sigma-band Rule requires both an `avg` and a `stdev` stat on the same channel. To view, edit, duplicate, or delete existing statistics, see [Manage Families](/documentation/analyze/families/keep-a-family-current#step-4-manage-statistics). ### Step 2: Create the Rule 1. On the Family overview page, click **Create Rule** in the **Family Analysis** section. This prepopulates the Family in the Rule editor. * Alternatively, go to **Rules** in the navigation and select **New Rule**, then configure the Family manually. 2. Choose one or more Assets to which the Rule applies. 3. In **Input Channels**, toggle **Aggregate Comparison**. 4. In **Aggregate Source**, select the Family. 5. In **Aggregate Channel Group Input**, select the statistics you created. For a sigma-band Rule, select both the `avg` and `stdev` statistics. When you select multiple statistics from the same Family, Sift uses the union of their alignment and dynamic window configurations for evaluation. 6. In **T-0 Alignment**, choose the alignment configuration defined on the Family. 7. Optionally select a **dynamic window** to scope the evaluation to a specific phase of the Run. You can create a new dynamic window without leaving the Rule editor by clicking **New window** in the dynamic window selector. ### Step 3: Write the Rule expression Reference the Channel under test with `$1` and the Family statistics with the variable placeholders assigned in the editor (for example, `$A` for avg, `$B` for stdev). **Sigma-band example**: flag when the channel falls outside mean ± 2 standard deviations: ``` ($1 < ($A - 2 * $B)) || ($1 > ($A + 2 * $B)) ``` **Envelope example**: flag when the channel falls outside the Family min/max: ``` $1 < $A || $1 > $B ``` Where `$A` is the min statistic and `$B` is the max statistic. For full syntax reference, see [Expression syntax](/documentation/reference/expression-syntax). ### Step 4: Preview the Rule 1. In **Rule Preview**, click **Select Run** and choose a sample Run. 2. Sift prompts you to resolve the alignment: map the Run's available alignment configurations to the Family's T-0 so the comparison is time-synchronized correctly. 3. Sift evaluates the Rule and plots the result. The Family statistic time series appears as a reference overlay alongside the Run's channel data in relative time. Annotations mark where the Rule condition is met. Review the output to confirm the expression fires when and only when you expect it to. ### Step 5: Save the Rule Click **Save**. Family Rules cannot be set to evaluate live; they run retrospectively when you generate a Report. To see all Rules that reference a given statistic, use the **Rule references** tab on the Family overview page. Rules are grouped by statistic, so you can identify downstream impact before editing or deleting a statistic. ### Step 6: Run the Rule in a Report 1. Open the Run you want to evaluate. 2. Click **Create report**. 3. Select the Family Rule and click **Evaluate**. 4. Sift prompts you to resolve the alignment for the Run before the Report generates. The alignment configuration used for the evaluation is recorded in the Report header. 5. The Report opens with the Family statistic overlay, the Run's channel data in relative time, and Annotations at each deviation. Each Annotation detail panel shows the absolute timestamp alongside the relative time offset from T-0. Add the Family Rule to a Report Template so you do not need to select it manually each time. See [Set up a repeatable review checklist](/documentation/review/set-up-a-repeatable-review-checklist). ## Verify the result After completing this workflow: * The Family statistics appear in the **Family Analysis** section of the Family overview page. * The Rule appears in the **Family Rules** section, located within the **Family Analysis** section of the Family Overview page. * The Report shows the Family statistic overlay, the Run's channel data in relative time, and Annotations at each point where the Rule fired. ## Next steps * To triage the Annotations generated by the Rule, see [Triage and close out flagged issues](/documentation/review/triage-and-close-out-flagged-issues). * To keep the Family current as new Runs arrive, see [Manage Families](/documentation/analyze/families/keep-a-family-current). * To understand how alignment, bucketing, and aggregation interact in detail, see [Families reference](/documentation/reference/families-reference). ## Reference * [Expression syntax](/documentation/reference/expression-syntax) * [Annotations reference](/documentation/reference/annotations-reference) # Group Runs into a Family Source: https://docs.siftstack.com/documentation/analyze/families/group-runs-into-a-family Create a named group of related Runs to use as a comparison baseline, statistical reference, and automated detection source. After completing this topic, you can create a Family, add members, and configure the alignment that makes cross-Run comparison meaningful. New to Families? Read the [Overview](/documentation/analyze/families/overview) to understand how members, alignments, statistics, and Rules work together before proceeding. ## When to use this workflow Use this workflow when you have a set of related Runs that represent a known-good or representative baseline and want to: * Compare new Runs against the historical spread visually in Explore * Compute aggregate statistics across the group (mean, standard deviation, min/max) * Build Rules that automatically flag when a new Run deviates from the group's statistical envelope A Family is the starting point for all of these workflows. ## Before you begin * You have at least two Runs ingested into Sift. * Your Sift account has the Editor role on the organization containing those Runs. See [Manage user access](/documentation/manage/manage-user-access). ## Complete the workflow ### Step 1: Create a Family 1. Select **Families** in the navigation. 2. Click **Create Family**. ### Step 2: Enter basic information Fill in the following: * **Family name**: A human-readable identifier; for example, `Engine 5 Nominal Acceptance Tests`. * **Description** (optional): What the Family represents and when to use it. * **Client key** (optional): A unique identifier for use in external systems or APIs. This cannot be changed after it is set. * **Metadata** (optional): Key-value pairs for tagging the Family with additional context, such as vehicle ID, test campaign, or configuration version. Metadata is searchable and filterable. ### Step 3: Add members In the **Membership** step, search for and add the Runs that represent your baseline. To add Runs individually: 1. Use the search field to find Runs by name or Asset. 2. Click **+** on each Run to include it, or select multiple Runs and use **Bulk Actions > Include in Family**. To exclude a Run from analysis while keeping it in the Family for reference: 1. Select the Run. 2. Click **−** or use **Bulk Actions > Exclude from Family**. 3. Optionally enter a rationale. The Run appears in the **Excluded** tab and is not counted in aggregate calculations. #### Use a candidate query to find members automatically A candidate query is a CEL expression evaluated against each Run. Runs that match appear in the **Candidates** tab, where you can bulk include or exclude them. 1. In the **Membership** step, click the **Candidates** tab. 2. Click **Add candidate query**. 3. Enter a CEL expression. For example, to match Runs whose name contains `flight` for a specific Asset: ```cel theme={null} name.contains('flight') && asset_name == 'rover-1' ``` Click **Show CEL documentation** in the editor for an inline syntax reference. To start from another Family's query, click **Import from existing Family** and select the source Family; Sift populates the editor with that Family's candidate query expression, which you can then modify. 4. Click **Run Query** to preview matching Runs. 5. Select the Runs and apply **Include** or **Exclude** from **Bulk Actions**. The query is saved with the Family. Any future Run that matches the query but has not been explicitly included or excluded surfaces as a candidate on the Family overview page. This is the mechanism that keeps a Family current over time without manual checking. See [Manage Families](/documentation/analyze/families/keep-a-family-current). ### Step 4: Configure alignments Alignments define how Runs are time-synchronized for comparison. Without an alignment, each Run's time axis starts at its own absolute start time, making cross-Run comparison meaningless. Configure at least one alignment: * **Run Start**: T-0 is set to the beginning of each Run. Use this for Runs with a consistent structure. * **Run End**: T-0 is set to the end of each Run. * **Timestamp**: T-0 is a fixed absolute time; use this when all Runs pass through a known moment. * **Annotation**: T-0 is set when a named event occurs in each Run, such as engine ignition or valve opening. Use this when the event of interest happens at different absolute times across Runs. You can define multiple alignments and switch between them in Explore or when configuring a Rule. Alignment names must be unique within the Family. **Phase Annotations for Annotation alignments**: An Annotation alignment resolves T-0 to the timestamp of a matching [Phase Annotation](/documentation/reference/annotations-reference#phase-annotations) on each Run. Mark the event you want to align on, such as flight computer startup, with a Phase Annotation of the same name on every Run in the Family before configuring the alignment. When you choose **Annotation** and click **Change**, the **Select Default Annotation** setting lists the Annotations found across your Runs. Select the Annotation that corresponds to the event you want to align on. For example, for a startup alignment, select the Phase Annotation that marks startup on each Run. ### Step 5: Save the Family Click **Save**. Sift creates the Family and records the initial state in version history. ## Verify the result After saving: * The Family appears under **Families** in the navigation with a member count and the alignments you configured. * Included members are listed under **Family Members**; excluded Runs appear under **Excluded**. * If you set a candidate query, the **Candidates** tab shows Runs that currently match. ## Next steps * To overlay all members in Explore on a shared time axis, see [Compare Runs visually against a Family baseline](/documentation/analyze/families/compare-runs-visually-against-a-family-baseline). * To compute aggregate statistics and write Rules that flag deviations, see [Detect statistical deviations using Family Rules](/documentation/analyze/families/detect-deviations-from-a-historical-baseline). * To add new Runs to the Family as they are ingested, see [Manage Families](/documentation/analyze/families/keep-a-family-current). # Manage Families Source: https://docs.siftstack.com/documentation/analyze/families/keep-a-family-current Update Family membership, configuration, and statistics as your test program evolves. After completing this topic, you can review candidate Runs, adjust membership, manage statistics, update alignments, and track configuration changes over time. New to Families? Read the [Overview](/documentation/analyze/families/overview) to understand how members, alignments, and statistics work together before proceeding. ## When to use this workflow Use this workflow on an ongoing basis after initial Family setup. As new Runs are ingested, the Family's candidate query surfaces matching Runs for review. This workflow covers how to act on those candidates, adjust membership, manage statistics, and update the Family configuration when your test program or requirements change. ## Before you begin * An existing Family. See [Group Runs into a Family](/documentation/analyze/families/group-runs-into-a-family). * A candidate query configured on the Family is recommended for automated candidate surfacing; see the candidate query step in [Group Runs into a Family](/documentation/analyze/families/group-runs-into-a-family#use-a-candidate-query-to-find-members-automatically). ## Complete the workflow ### Step 1: Review candidate Runs In the Family overview page, if the Family has a candidate query and unreviewed matching Runs exist, the page shows a **N Family candidates to review**. 1. Click the callout to open the Family in edit mode on the **Candidates** tab. 2. Review the matching Runs and decide whether each one belongs in the Family. 3. Select the Runs you want to act on and use **Bulk Actions > Include in Family** or **Exclude from Family**. 4. When excluding, enter a rationale. This is stored in version history. 5. Click **Save**. You can also review candidates from an active Explore session without navigating away. Hover over the Family in the data source panel to see the candidate count, then click **Review Run(s)** to inspect them in Explore before committing. ### Step 2: Add or exclude members manually To update membership outside the candidate flow: 1. Open the Family overview page. 2. Click **Edit**. 3. In the **Membership** step, use the search field to find Runs by name or Asset. 4. Use **+** to include or **−** to exclude each Run. 5. Click **Save**. Every save creates a new version history entry. ### Step 3: Edit the candidate query To change the CEL expression that surfaces candidate Runs: 1. In the Family overview, click **Edit Family**. 2. In the **Membership** step, click **Edit candidate query**. 3. Update the CEL expression. Click **Show CEL documentation** in the editor for syntax reference. 4. Click **Preview** to verify the updated query returns the expected Runs. 5. Click **Save**. ### Step 4: Manage statistics Statistics compute aggregate time series across all included members. You can view, edit, duplicate, or delete them from the **Family Analysis** section of the Family overview page. **To view a statistic**: Click the statistic name to open the preview. The preview shows the aggregate time series and the `input_count` diagnostic series. **To edit a statistic**: 1. Open the statistic options and click **Preview/Edit Stat**. 2. Update the channel, aggregation type, output rate, data ranges, or fallback channels. 3. Click **Save**. Sift recomputes the statistic with the updated configuration. **To duplicate a statistic**: Open the statistic options and click **Duplicate**. Sift creates a copy with the same configuration, which you can then edit independently. **To delete a statistic**: Deleting a statistic cannot be undone. Before deleting a statistic, check which Rules reference it. The **Rule references** tab on the Family overview page lists all dependent Rules grouped by statistic. Open the statistic options and click **Delete**. This action cannot be undone. ### Step 5: Update alignments If your test program has changed, for example, a new event type has been introduced or a channel has been renamed, you may need to update the alignment configuration. 1. Open the Family in edit mode. 2. In the **Align Data** step, edit the alignment name, type, or reference event. 3. Click **Save**. ### Step 6: More options The **More options** menu (the **⋮** button on the Family overview page) provides the following actions. **Share**: Copies a shareable link to the Family overview page to your clipboard. **Duplicate**: Creates a copy of the Family with the same configuration, members, statistics, and alignments. The duplicate opens as a new draft for you to rename and modify before saving. **Download YAML**: Downloads the Family's full configuration as a YAML file. Use this to version-control configurations outside Sift, share configurations across environments, or seed a new Family from an existing one. **Upload YAML**: Replaces the Family's configuration with a YAML file you provide. On save, Sift validates field names and returns an error for any unrecognized field. Invalid field values are automatically corrected. **Edit as YAML**: Opens the Family configuration in an inline YAML editor. Click **Save** when done. On save, Sift validates field names and returns an error for any unrecognized field. Invalid field values are automatically corrected. **Archive**: Marks the Family as read-only. See [Archive a Family](#archive-a-family) below. **View Family Docs**: Opens the Families documentation in a new tab. ### Step 7: Review version history and revert Every save to a Family creates a version history entry. To review the history: 1. Open the Family overview page. 2. Click the **Version history** tab. Each entry shows the version ID, timestamp, author, and a description of what changed. **To revert to a previous version**: 1. In the **Version history** tab, find the version you want to restore. 2. Click **Revert to this version**. 3. Confirm. Sift creates a new version history entry recording the revert. ## Archive a Family When a test program is complete and the Family no longer needs to be updated, archive it to mark it as read-only. 1. On the Family overview page, click **More options**. 2. Select **Archive** and confirm. Archived Families remain visible in lists and can be filtered by archive status. Rules that reference statistics from an archived Family continue to evaluate normally. To modify the Family, unarchive it first. ## Verify the result After working through this workflow: * The Family member count reflects your current review decisions. * Excluded Runs appear in the **Excluded** tab with their recorded rationale. * Version history shows a complete audit trail of all changes. * Any updated statistics have been recomputed and are available in Explore and Rules. ## Next steps * To visualize the updated Family in Explore, see [Compare Runs visually against a Family baseline](/documentation/analyze/families/compare-runs-visually-against-a-family-baseline). * To update Family Rules after a configuration change, see [Detect statistical deviations using Family Rules](/documentation/analyze/families/detect-deviations-from-a-historical-baseline). # Overview Source: https://docs.siftstack.com/documentation/analyze/families/overview **Families** in Sift are named groups of related Runs used for comparison, analysis, and historical baselines. For example, group all known-good acceptance test Runs for an engine configuration into a Family, then evaluate each new Run against the Family's chamber pressure mean and standard deviation to flag deviations from the baseline. Once a Family is defined, you can overlay members on a shared time axis, compute aggregate statistics, and build Rules that flag when a new Run deviates from the baseline. See [When to use Families](#when-to-use-families) for more example workflows. ## Key concepts Families are built from four core elements: ## When to use Families Use Families when historical data defines standard behavior and you want to compare new Runs against that baseline. ## Alignments During hardware tests or operations, events occur at different absolute times and sequences vary in terms of duration, so it can be hard to make direct comparisons. Alignments solve this by defining a shared T-0 reference point for each Run, enabling direct comparison. A Family can have multiple alignments, and you can switch between them when visualizing Runs in Explore or configuring a Rule. You can align Runs to the following: * **Run start or end**: T-0 is set to the beginning or end of each Run. This works well for Runs with consistent structure. * **A specific timestamp**: T-0 is a fixed absolute time, useful when all Runs pass through a known moment. * **An Annotation**: T-0 is set when a named event occurs within each Run, such as an engine ignition or valve opening. Use this when the event happens at different absolute times across Runs. The alignment resolves to a [Phase Annotation](/documentation/reference/annotations-reference#phase-annotations) of the same name on each Run; mark the event with a Phase Annotation before configuring the alignment. ## Family statistics Family statistics compute aggregate time series across all included members. When you save a Family statistic, Sift fetches data from each included Run in the configured time window, converts it to relative time using the alignment, and computes the aggregate at each time step. Supported aggregation types: Statistics can be scoped to specific time windows within a Run. For example, scoping for the 30 seconds after engine ignition only, using data ranges configured on the statistic. ## Family rules Family rules use computed statistics as dynamic thresholds in rule expressions. A common pattern compares a Channel from a Run under test against a sigma band derived from the Family's `avg` and `stdev` statistics. When evaluating a Family rule against a new Run, Sift prompts you to map the Run's alignment configuration to the Family's alignment so the comparison is time-synchronized correctly. Results appear in reports that show the Family statistic overlay alongside the Run's Channel data in relative time. Family Rules do not support live (real-time) evaluation. They are intended for retrospective analysis after a Run completes. ## Version history Every change to a Family, including adding or removing members and updating alignments or statistics, creates a new version with a record of what changed and when. Version history is visible on the Family overview page and provides an audit trail of how the reference dataset changed over time. ## How-to guides * [Group Runs into a Family](/documentation/analyze/families/group-runs-into-a-family) * [Compare Runs visually against a Family baseline](/documentation/analyze/families/compare-runs-visually-against-a-family-baseline) * [Detect statistical deviations using Family Rules](/documentation/analyze/families/detect-deviations-from-a-historical-baseline) * [Manage Families](/documentation/analyze/families/keep-a-family-current) # Investigate a telemetry anomaly Source: https://docs.siftstack.com/documentation/analyze/investigate-telemetry-anomaly Isolate unusual signal behavior, compare related Channels, and identify the root cause of an anomaly. After completing this topic, you can narrow down the root cause of an anomaly by isolating the affected time range and comparing related signals. ## Before you begin * You have a Run with an identified anomaly open in [Explore](/documentation/reference/explore-settings) with the affected Channel plotted. ## How anomaly investigation works When a signal shows unexpected behavior, you can zoom into the affected time range and plot related Channels side by side to determine whether the anomaly is isolated to a single signal or correlated across multiple signals. Comparing related Channels helps narrow down the root cause, such as a sensor failure, an environmental event, or a system-level issue. ## Investigate an anomaly 1. In the toolbar, select a [range control](/documentation/reference/explore-settings#range-controls) to zoom into the time range where the anomaly occurs. * Range controls are available in Timeseries, FFT, and Scatter Plot Panels. 2. Add related Channels to the same Panel or [split](/documentation/reference/explore-settings#layout) the Panel by right-clicking its tab and selecting a split direction to compare signals in an adjacent Panel. 3. Optional: Create a [Calculated Channel](/documentation/reference/explore-settings#calculated-channels) to derive a signal that highlights the anomaly, such as a difference or ratio between two Channels: 1. Click the **Calculated Channels** tab. 2. Click **Create new Calculated Channel**. 3. Select the **Asset** to attribute the Calculated Channel. 4. In the **Calculated Channel name** box, enter a name. 5. Click the **Input Channels** list. 6. In the **Expression** box, enter the CEL expression. * To learn more, see [Expression syntax](/documentation/reference/expression-syntax). 7. Optional: In the **Unit** box, enter a unit. 8. Optional: Turn on the **Save to Asset** toggle to save the Calculated Channel for future reuse. 9. Click **Add Calculated Channel**. 4. Optional: Add an [Annotation](/documentation/reference/explore-settings#annotations) to mark the anomaly for review or to share with your team: * In the **Annotations** tab, click **Create new Annotation**, select a type (**Phase** or **Data Review**), configure the fields, and click **Add Annotation**. Select **Data Review** if the anomaly needs to be tracked to resolution; select **Phase** to mark it as a reference point without a status. * Alternatively, click **Select X**, drag over the time range in the Timeseries Panel, right-click the selection, and select **Create Annotation**. 5. Optional: In **Explore**, click [**Share**](/documentation/reference/explore-settings#share) to send the exact state of your investigation to another engineer. 6. Optional: Create a [Rule](/documentation/review/detect-deviations-automatically-using-rules) to automatically detect the same anomaly in future Runs. ## Reference * [Explore settings](/documentation/reference/explore-settings) # Monitor telemetry in real time Source: https://docs.siftstack.com/documentation/analyze/monitor-telemetry-in-real-time Use Live mode in Explore to monitor real-time telemetry as it streams into Sift. After completing this workflow, you can use Live mode to watch telemetry populate your Panels in real time as it streams into Sift, without waiting for the Run to complete, so you can monitor system health, track signal behavior, or catch anomalies as they happen. ## Before you begin * You have an active data stream sending telemetry to Sift. * See [Stream](/documentation/ingest/stream) for supported ingestion mechanisms. * You know the name of the Run being created by your stream. ## How Live mode works Live mode monitors real-time telemetry as it streams into Sift. All [Panel types](/documentation/reference/explore-settings#panel-types) support Live mode. You can configure how frequently Panels refresh and how the screen updates as new data arrives. [Panel Sync](/documentation/reference/explore-settings#sync-panels) is compatible with Live mode. When both are active, all synced Panels advance together as new data streams in. ## Monitor telemetry in real time 1. Select **Runs** in the navigation, then enter the Run name in the **Run name or description** field. 2. In the **Runs** table, click the Run. 3. Click **Explore**. 4. Select a [Panel type](/documentation/reference/explore-settings#panel-types) to add to the workspace. 5. In the **Channels** tab, click or drag a Channel onto the Panel to plot it. 6. Click **Live**. 7. Optional: In the **Refresh every 1s** list, select how frequently your Panels refresh. 8. Optional: In the **Smooth Scroll** list, select how the Panels update as new data arrives. ## Monitor current state with the Stat panel The Stat panel displays the most recent value for each channel as a tile, updating on the 1-second tick in Live mode. Use it alongside Timeseries panels to watch current state while retaining the ability to scrub back when something looks wrong. | Use case | What to monitor | | ------------------------- | -------------------------------------------------- | | Yield monitoring | Pass/fail rate per test station | | Throughput monitoring | Cycle time and units per hour | | Station health monitoring | Current health signals across a test station | | Production run tracking | Key values for a batch as it moves through testing | ## Verify Once Live mode is enabled, your Panels update automatically as new telemetry streams in. ## Reference * [Explore settings](/documentation/reference/explore-settings) # Standardize analysis across Runs Source: https://docs.siftstack.com/documentation/analyze/standardize-analysis-across-runs Save your analysis setup once and apply it to any dataset without rebuilding from scratch. After completing this workflow, you can save a Panel's Channel selection and chart settings once as a Panel Configuration and apply them to any Run, swapping only the data source instead of rebuilding the layout each time. ## Before you begin * You have a Run with ingested telemetry data open in [Explore](/documentation/reference/explore-settings). ## How Panel Configurations work A Panel Configuration saves a Panel's visualization setup, including Channel selection and chart settings, so it can be applied to any Panel in any future session. When you open Explore for a new Run, you apply the configuration and only swap the data source. Your Channels, layout, and settings are already in place. ### Example For example, a team reviewing battery health after every engine test can save their standard voltage, current, and temperature Channels once and open the same layout for every new Run, without rebuilding it each time. ## Save a Panel Configuration 1. In **Explore**, plot the Channels you want to reuse in a Panel. 2. In the Panel, click to open the Panel settings and configure them as needed. 3. Click **Save configuration as...**. 4. In the **Panel Configuration Name** box, enter a name for the Panel Configuration. 5. Optional: Clear **Channel List & Settings** to exclude Channel selections from the configuration. 6. Optional: Clear **Timeseries Panel Settings** to exclude chart settings from the configuration. 7. Click **Save**. * If your standard Channel set or settings change, you can update the configuration. See [Overwrite a Panel Configuration](#overwrite-a-panel-configuration). ## Apply a Panel Configuration to a new Run 1. Select **Runs** in the navigation, then search for the Run you want to analyze with a Panel Configuration. 2. In the **Runs** table, click the Run. 3. Click **Explore**. 4. Click the **Panel Configurations** tab. 5. Select the Panel Configuration you want to apply. * Only Panel Configurations that have at least one Channel name matching the selected data source are shown. 6. Select how you want to apply the configuration and click **Apply**. 7. Optional: To swap the data source without rebuilding the layout, right-click a data source in the **Channels** tab, select **Replace data source**, choose a replacement Run or Asset, click **Preview changes**, review any warnings, and click **Confirm replacement**. ## Overwrite a Panel Configuration When your standard Channel set or settings change, overwrite the existing configuration to keep it up to date. 1. Apply a Panel Configuration to a Panel. 2. Update the Channels or settings in the Panel as needed. 3. In the Panel, click to open the Panel settings. 4. Click **Save configuration as...**. * The **Overwrite Existing** tab is selected by default with the last applied configuration pre-selected. 5. Optional: Select a different Panel Configuration to overwrite from the **Existing Configuration to Overwrite** list. 6. Click **Save**. ## Reference * [Explore settings](/documentation/reference/explore-settings) # Export data with the Sift CLI Source: https://docs.siftstack.com/documentation/cli/export-data-with-the-sift-cli Export Run and Asset telemetry from Sift to a file from the command line. After completing this workflow, you can export telemetry from a Run or an Asset to a file from the command line, for downstream analysis, sharing, or archiving. ## Before you begin * Install and configure the CLI. See [Sift CLI setup](/documentation/cli/sift-cli). * For every command, flag, and supported value, see the [Sift CLI reference](/documentation/reference/cli-reference). ## Import commands Both export commands share these flags: * `--output` / `-o`: the file to generate. Required. * `--format` / `-f`: the output format. Required. Accepts `csv`, `parquet`, or `sun` (WinPlot). * `--channel` / `-c`: a Channel name to include. Repeat the flag to add more. * `--channel-id`: a Channel ID to include. Repeat the flag to add more. * `--channel-regex` / `-x`: a regular expression that selects Channels by name. * `--calculated-channel`, `--calculated-channel-id`, `--calculated-channel-regex`: the same selectors for Calculated Channels. ## Export a Run Identify the Run by name, ID, or client key. These three selectors are mutually exclusive. ```bash theme={null} sift-cli export run --name "my-run" \ --output ./run.parquet \ --format parquet \ --channel voltage \ --channel current ``` | Selector | Flag | | ---------- | --------------------- | | Name | `--name` / `-n` | | Run ID | `--run-id` / `-r` | | Client key | `--client-key` / `-k` | To include Calculated Channels, add them with the calculated-channel selectors: ```bash theme={null} sift-cli export run --run-id \ --output ./run.csv \ --format csv \ --calculated-channel-regex "power.*" ``` ## Export an Asset Pass the Asset name as a positional argument. Asset exports require a time range set with `--start` and `--stop` in RFC 3339 format. ```bash theme={null} sift-cli export asset my-asset \ --output ./asset.csv \ --format csv \ --start 2026-01-01T00:00:00Z \ --stop 2026-01-02T00:00:00Z \ --channel-regex "temp.*" ``` # Import files with the Sift CLI Source: https://docs.siftstack.com/documentation/cli/import-files-with-the-sift-cli Import CSV, Parquet, TDMS, HDF5, ULog, and backup files into Sift from the command line. After completing this workflow, you can import CSV, Parquet, TDMS, HDF5, ULog, or backup files into an Asset from the command line, without writing code against the API. ## Before you begin * Install and configure the CLI. See [Sift CLI setup](/documentation/cli/sift-cli). * Identify the Asset that owns the data. When you import, you can name an existing Asset or a new one. * Confirm your file has a time column in a [supported time format](#time-formats). * For every command, flag, and supported value, see the [Sift CLI reference](/documentation/reference/cli-reference). ## Import commands Every import command imports into an Asset named by `--asset`. To associate the data with a Run, or to create or reuse a Run by name, pass `--run `. To append to an existing Run, use `--run-id `. The CSV importer accepts `--run` only. Two flags apply to all import commands: * `--preview` parses the file and prints the detected schema without uploading. * `--wait` blocks until Sift finishes processing the import. ## Import a CSV file Import a CSV file into an Asset. Unless you specify column types, the CLI infers each column as either string or double. ```bash theme={null} sift-cli import csv ./data.csv --asset my-asset --wait ``` To override specific columns, pass `--channel-column` with the 1-based column index. Supply a `--data-type`, `--unit`, and `--description` for each `--channel-column`. The counts must match. Units and descriptions can be empty strings. ```bash theme={null} sift-cli import csv ./data.csv \ --asset my-asset \ --channel-column 2 --data-type double --unit volts --description "" \ --channel-column 3 --data-type bool --unit "" --description "" ``` CSV import defaults the header row to row 1, the first data row to row 2, and the time column to column 1. Override these with `--header-row`, `--first-data-row`, and `--time-column`. Set the time format with `--time-format`. ## Import a Parquet file Parquet import has two layouts. Choose the subcommand that matches your file. ### Flat dataset Use `flat-dataset` when every column holds one Channel, except for the time column. By default, the CLI imports every non-time column. ```bash theme={null} sift-cli import parquet flat-dataset ./data.parquet --asset my-asset ``` To import a subset of columns, pass `--channel-path` for each Channel. Supply a `--data-type`, `--unit`, and `--description` for each `--channel-path`. The counts must match. Units and descriptions can be empty strings. ```bash theme={null} sift-cli import parquet flat-dataset ./data.parquet \ --asset my-asset \ --channel-path voltage --data-type double --unit volts --description "" \ --channel-path current --data-type double --unit amps --description "" ``` The CLI auto-detects the time column from the common names `time`, `timestamp`, `timestamps`, and `ts`. Set `--time-path` to name it explicitly. The CLI infers the time format from the column's Arrow type unless you set `--time-format`. ### Channel per row Use `cpr` when the file is laid out one Channel value per row. The `--mode` flag selects the layout: * `single`: the file holds `[time, value]` and every row belongs to one Channel. Name it with `--channel-name`. * `multi`: the file holds a name column and a value column. Set `--name-path` to the column holding Channel names. The CLI creates a Channel per unique name. ```bash theme={null} sift-cli import parquet cpr ./data.parquet \ --asset my-asset \ --mode multi \ --data-path value \ --name-path channel ``` Both Parquet layouts handle complex columns (maps, lists, structs) through `--complex-types-mode`, which defaults to `ignore`. ## Import a TDMS file Import a TDMS file into an Asset. ```bash theme={null} sift-cli import tdms ./data.tdms --asset my-asset ``` For Channels with missing timing information, `--fallback-method` controls behavior and defaults to `fail-on-error`. Set it to `ignore-error` to skip those Channels. To import TDMS file properties to the Run as metadata, pass `--import-file-properties`. ## Import an HDF5 file Import an HDF5 file into an Asset. Two flags are required: `--schema`, which names the file's layout (`one-d`, `two-d`, or `compound`), and `--time-format`. Add `--relative-start-time` (`-s`) when the time format is relative. ```bash theme={null} sift-cli import hdf5 ./data.h5 --asset my-asset --schema one-d --time-format absolute-unix-seconds ``` HDF5 import supports these Channel types across all schemas: `bool`, `int8/16/32/64`, `uint8/16/32/64`, `float32`, and `float64`. Datasets with other types produce a client-side error. The time-column flag depends on the schema: * `--time-name` (one-d): the leaf name of the time dataset when it differs from the auto-detected names `time`, `timestamp`, `timestamps`, or `ts`. * `--time-index` (two-d): the index of the time column. Defaults to 0. * `--time-field` (compound): the name of the time field. ## Import a ULog file Import a PX4 ULog file into an Asset. ULog files are self-describing, so the CLI imports every logged topic by default, naming each Channel `_.` (for example `sensor_accel_0.x`). Logged status text becomes `log_messages` Channels. ```bash theme={null} sift-cli import ulog ./flight.ulg --asset my-asset --wait ``` ULog timestamps are relative to boot time. Sift anchors the timeline using the log's GPS time fix, unless you provide an explicit start time with `--relative-start-time` (`-s`), which takes precedence: ```bash theme={null} sift-cli import ulog ./flight.ulg --asset my-asset --relative-start-time 2026-07-02T15:04:05Z ``` To import ULog info messages or parameter values as Run metadata, pass `--info-key` or `--param-key` for each one. Both require `--run` or `--run-id`: ```bash theme={null} sift-cli import ulog ./flight.ulg \ --asset my-asset \ --run "test flight 2026-07-02" \ --info-key sys_name \ --param-key MC_PITCH_P ``` If the file ends with a truncated record or contains corrupt segments, the import fails by default. Pass `--parse-error-policy ignore-error` to import the records that parsed and skip the rest. ## Import backup files Import backup files generated by [sift\_stream](/documentation/reference/asset-settings#stream), part of the `sift_app` built-in system Asset. If ingestion fails, `sift_stream` writes the in-flight data to a local backup. `sift-cli import backups` will replay them and import anything that did not make it into Sift. ```bash theme={null} sift-cli import backups --path ./backups ``` If you omit `--path`, the CLI reads from your OS data directory. Pass `--cleanup` to delete the backup files after a successful upload. To list backup files without importing them: ```bash theme={null} sift-cli import backups ls ./backups ``` ## Time formats The `--time-format` flag accepts absolute and relative values. For the full list, see the [Sift CLI reference](/documentation/reference/cli-reference#time-formats). For a relative format, set the relative start time (`-s`, or `--relative-start-time` on Parquet, TDMS, and HDF5) to an RFC 3339 timestamp that anchors the offsets. # Sift CLI setup Source: https://docs.siftstack.com/documentation/cli/sift-cli Install, configure, and run the Sift CLI to import and export telemetry from the command line. The Sift CLI is a command-line tool for moving telemetry in and out of Sift without writing code. Use the CLI when you want to: * Import CSV, Parquet, TDMS, HDF5, and ULog files from a terminal or a script. * Export Run and Asset data to CSV, Parquet, or Sun (WinPlot) format. * Verify API credentials and connectivity. The binary is named `sift-cli` (formerly `sift_cli`). It is a standalone command-line tool, distinct from the `sift_client` Python client library. For every command, flag, and supported value, see the [Sift CLI reference](/documentation/reference/cli-reference). ## Install the CLI ```bash theme={null} curl --proto '=https' --tlsv1.2 -LsSf https://api.siftstack.com/install/sift-cli | sh ``` ```powershell theme={null} powershell -ExecutionPolicy Bypass -c "irm https://api.siftstack.com/install/sift-cli.ps1 | iex" ``` For Sift GovCloud, replace `api.siftstack.com` with `api.gov.siftstack.com`. To install a specific version, append the version number without a `v` prefix. For example, use `https://api.siftstack.com/install/sift-cli/0.5.0`. ## Configure a profile The CLI reads connection settings from a `sift.toml` config file stored in your user data directory. Each profile holds a gRPC endpoint, a REST endpoint, an API key, and the URL of your Sift web app. ```bash theme={null} sift-cli config create ``` This command fails if a config file already exists. Obtain the gRPC and REST base URLs and an API key from the Sift UI. See [Set up API access](/documentation/manage/set-up-api-access). ```bash theme={null} sift-cli config update \ --grpc-uri $SIFT_GRPC_URI \ --rest-uri $SIFT_REST_URI \ --api-key $SIFT_API_KEY \ --app-uri $SIFT_APP_URI ``` `--app-uri` is the URL of your Sift web app, such as `https://app.siftstack.com` or `https://gov.siftstack.com`. Set it so that `sift-cli import` prints an Explore link for the data it uploads. A custom or on-premises deployment requires it. ```bash theme={null} sift-cli config show ``` To print the path to the config file instead, run `sift-cli config where`. To enter values through prompts instead of flags, use the interactive flag: ```bash theme={null} sift-cli config update --interactive ``` Commands run against the `default` profile unless you pass `--profile `. The `--profile` flag is global and applies to any command. ```bash theme={null} sift-cli ping --profile mission ``` To connect to a non-cloud Sift environment that does not use TLS, pass the global `--disable-tls` flag. ## Manage multiple environments If you connect to more than one environment, each environment requires its own API key; the REST and gRPC URIs are shared across environments in the same account. Create a separate key for each environment, and use the matching key when you authenticate a request against that environment. To manage this from the CLI, create a separate profile for each environment. Reuse the same gRPC endpoint, REST endpoint, and app URI as your default profile, and set the API key for the new environment: ```bash theme={null} sift-cli config update --profile mission \ --grpc-uri $SIFT_GRPC_URI \ --rest-uri $SIFT_REST_URI \ --app-uri $SIFT_APP_URI \ --api-key $SIFT_ENVIRONMENT_API_KEY ``` `config update` creates the profile if it doesn't already exist. Pass `--profile ` to any command to run it against that environment: ```bash theme={null} sift-cli ping --profile mission ``` ## Verify connectivity Confirm that your profile's credentials and endpoint work: ```bash theme={null} sift-cli ping ``` The command pings the Sift API and prints the response. ## Import and export data The CLI's primary workflows are file import and data export: Import CSV, Parquet, TDMS, HDF5, ULog, and backup files into an Asset. Export Run or Asset data, including Calculated Channels, to a file. For every command, flag, and supported value, see the [Sift CLI reference](/documentation/reference/cli-reference). ## Install shell completions Install command autocompletions for your current shell, then restart the shell: ```bash theme={null} sift-cli install completions update ``` To print completions for a specific shell instead of installing them, name the shell: ```bash theme={null} sift-cli install completions print --shell zsh ``` If you omit `--shell`, the CLI infers the shell from the `$SHELL` environment variable. ## Serve the docs locally Serve the CLI's bundled documentation over HTTP: ```bash theme={null} sift-cli doc ``` The server binds to `0.0.0.0:3000` by default. To bind a different address, pass `--addr`: ```bash theme={null} sift-cli doc --addr 127.0.0.1:8080 ``` # Sift MCP server Source: https://docs.siftstack.com/documentation/cli/sift-mcp Connect AI coding agents to Sift with the Sift Model Context Protocol server. The [Sift CLI](/documentation/cli/sift-cli) includes a [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that exposes Sift to Al coding agents as structured tools. A connected agent can do the following: * Ingest and discover data * Perform analysis and transformations * Create Sift entities Once connected, your client lists the tools the server exposes. Use the Sift MCP server when you want an agent to work against your Sift environment directly. The `sift-cli agent` command installs and maintains that connection for every supported client on your machine. Supported clients: * [Claude Code](https://claude.com/claude-code) * [Codex](https://github.com/openai/codex) * [Cursor](https://cursor.com) * [OpenCode](https://opencode.ai) ## Prerequisites Configure the Sift CLI profile before you install the integration. The MCP server reads its endpoint and API key from that profile. 1. Install the CLI and [configure a profile](/documentation/cli/sift-cli#configure-a-profile). 2. Confirm the profile works: ```bash theme={null} sift-cli ping ``` ## Install the integration ```bash theme={null} sift-cli agent install ``` This command detects every supported client and installs the files for each client: * **Skills** that teach the agent how to interact with Sift by combining the MCP server, the CLI, the REST API, and the client libraries. * **An MCP registration** that points the client at the `sift-cli` executable that ran the command. By default, the agent has ***read-only*** access to Sift until you enable write access, and the install uses the `default` profile. Nothing is written until every target passes a preflight check, and the command refuses to overwrite a same-name skill or MCP entry that Sift does not manage. To install against a named profile instead, pass the profile name, for example, `mission`: ```bash theme={null} sift-cli agent install --profile mission ``` To ensure the client picks up the new registration, reload or restart the client. ### Integration files locations The CLI detects Claude Code and Codex by their command on your `PATH`. It detects Cursor and OpenCode by their command or their configuration directory. **Path dependency**: The MCP registration records the absolute path of the `sift-cli` executable that ran the install. If you move or reinstall the binary, run `sift-cli agent update` to point the clients at the new path. ## Gated tools By default, tools that modify or archive existing resources are disabled. When an agent calls a disabled tool, the server returns an error stating that access is disabled. The gated tools are `update_asset`, `update_run`, `update_report`, `update_annotation`, `update_rule`, `archive_rule`, and `unarchive_rule`. Additive writes stay available without the flag: `create_annotation`, `create_report`, `create_rule`, `create_test_report`, `append_test_measurements`, and `upload_dataset`. **Replace, not merge**: `--allow-destructive` lets an agent overwrite and archive existing Sift resources. `update_asset`, `update_run`, `update_report`, and `update_annotation` replace tags, metadata, and other collections rather than merging them. Enable it only when you intend to give the agent that access. To enable gated tools for every detected client: ```bash theme={null} sift-cli agent update --allow-destructive ``` To return every client to read-only: ```bash theme={null} sift-cli agent update --read-only ``` If you do not specify an access mode, the default is `--read-only`. Reload each client after changing its access mode. ## Context and API guardrails The MCP server includes guardrails to keep agent sessions within context and API limits: * List-style tools default to a page size of 50 items, capped at 200. This is lower than the default page size elsewhere in Sift's web and API surfaces, and is intended to keep large result sets from filling an agent's context window. * Tools prompt the agent to filter down broad or ambiguous queries instead of paging through large result sets. * The installed skill includes general prompt guidance on being a good steward of the API and its limits. * Failed API calls retry automatically with backoff, so a transient failure doesn't overload the API or trigger rate limiting. ## Why the server runs locally The MCP server runs locally via `sift-cli` rather than as a hosted endpoint: * The MCP ships a `data/sql` tool that runs SQL locally against data downloaded with `data/get_data`, so an agent can do more complex analysis without a round trip to Sift. * Installing locally lets Sift ship the skill as a `SKILL.md` file, versioned alongside MCP upgrades, that loads instructions into context progressively. This keeps tool descriptions lighter and reduces token consumption over a session. * Because the MCP ships with `sift-cli`, installing it also gives you whatever else the CLI provides, such as dataset import and export. ## Check the integration `sift-cli agent doctor` reports the state of the installed files and client configurations without changing them. It also checks GitHub for a newer CLI release. ```bash theme={null} sift-cli agent doctor ``` ```text theme={null} Sift agent bundle X.Y.Z [ok] sift-cli X.Y.Z is current Detected: Claude Code, Codex, Cursor, OpenCode [ok] Codex/Cursor/OpenCode skill: /Users/you/.agents/skills/sift [ok] Claude Code skill: /Users/you/.claude/skills/sift [ok] Claude Code MCP registration (read-only, default profile) [ok] Codex MCP registration (read-only, default profile) [ok] Cursor MCP registration (read-only, default profile) [ok] OpenCode MCP registration (read-only, default profile) All detected Sift agent integrations are healthy. ``` `doctor` reports an error when a skill is missing, a skill came from a different CLI release, an MCP registration is missing or has drifted, or the detected clients disagree on access mode or profile. Each error is followed by the command that repairs it. To assert that every client uses a specific profile, pass the profile name, for example, `mission`: ```bash theme={null} sift-cli agent doctor --profile mission ``` ## Example prompts Adapt these prompts to your own Assets and Runs. The installed skill tells the agent which tools to chain for each one. Each example shows an abridged response to give you a sense of what the agent returns. Your own responses differ by client, by model, and by the data in your environment. ### Find your recent Runs The agent resolves your identity from the API key in your profile, then filters Runs by creator. ```text theme={null} Which runs did I create in the last week? ``` > You created three Runs in the last week: `acceptance-07`, `thermal-cycle-12`, > and `regression-04`. ### Investigate a signal The agent downloads the Channel data to a Parquet file, then queries it with SQL to find the samples you asked about. ```text theme={null} Download the temperature channels for run acceptance-07 and tell me where any of them exceeded 80C. ``` > I downloaded four temperature Channels for `acceptance-07` and queried them. > Two exceeded 80C: `motor_temp_2` peaked at 87.4C between 00:14:22 and > 00:14:51, and `motor_temp_3` reached 81.9C at 00:14:36. ### Open a view in Explore The agent returns a Sift Explore link that opens your selection. ```text theme={null} Give me an Explore link for the bus voltage channels on run acceptance-07. ``` > `https://app.siftstack.com/explore?method=single&runs=acceptance-07&channels=bus_voltage_1,bus_voltage_2` ### Record a finding The agent creates an Annotation over the time range it identified. ```text theme={null} Annotate the voltage drop you found on run acceptance-07 and assign it to me. ``` > I created the Annotation "Bus voltage drop" on `acceptance-07`, covering > 00:14:22 to 00:14:51, and assigned it to you. ### Derive and upload a dataset The agent downloads the source Channels, computes the new series with SQL, and streams the result back into Sift as a dataset. ```text theme={null} Compute a 10-second rolling average of the temperature channels on run acceptance-07 and upload it to the same asset. ``` > I computed a 10-second rolling average for four temperature Channels and > uploaded the result to the Asset as `motor_temp_2_avg_10s` and three > sibling Channels. ### Look up how Sift works The agent searches the Sift documentation and API reference, then reads the matching pages. ```text theme={null} How can I set up data ingestion for a new asset? ``` > I searched the Sift documentation and read the ingestion pages. Here are the > options for getting data into a new Asset, with links to each source page. ## Update every client Update refreshes the skill and MCP registration for every detected client and preserves the existing access mode and profile. If a newer CLI release exists, update stops and prints the installer command to run. ```bash theme={null} sift-cli agent update ``` `sift-cli agent install` and `sift-cli agent update` act on all detected clients together. The CLI treats mixed access modes or mixed profiles as an error rather than picking one, so resolve them with an explicit access mode (`--allow-destructive` or `--read-only`) or profile, for example, `mission`: ```bash theme={null} sift-cli agent update --profile mission ``` ## Switch profiles Point every detected client at a named profile, for example, `mission`: ```bash theme={null} sift-cli agent update --profile mission ``` Return every detected client to the `default` profile: ```bash theme={null} sift-cli agent update --default-profile ``` Reload each client after switching profiles. ## Configure a client manually For a client that `sift-cli agent install` does not support, register the server yourself. Most MCP clients take a command and arguments: ```json theme={null} { "mcpServers": { "sift": { "command": "sift-cli", "args": ["mcp"] } } } ``` The client launches the server over stdio instead of running it interactively. Add `--profile ` to select a profile (for example, `mission`) and `--allow-destructive` to enable the gated tools: ```json theme={null} { "mcpServers": { "sift": { "command": "sift-cli", "args": ["mcp", "--profile", "mission", "--allow-destructive"] } } } ``` ## Remove the integration Uninstall removes the skill files and MCP registrations that Sift manages, and leaves everything else in place. It reports what it removed and what was not installed. ```bash theme={null} sift-cli agent uninstall ``` # Export data to a file Source: https://docs.siftstack.com/documentation/export/export-data-from-a-file Export telemetry data from a Run to a file for downstream analysis, sharing, or archiving. After completing this workflow, you can download telemetry data from a Run to a file for use in external tools or for archiving. ## Before you begin * You have a Run with ingested telemetry data. * Choose the export method that fits your use case. Supported file types vary by method. ## How data export works Sift exports telemetry data from a Run to a downloadable file. You can export all Channels in a Run or a specific selection. Exports run in the background so you can continue working while your file is prepared. When exporting from the UI, you can do so in two ways: * **From a Run's overview page**: select specific Channels and export them directly. * **From Explore**: export the Channels currently plotted in a Timeseries Panel from an active Explore session. Both UI paths support the same export formats. For programmatic exports, use the REST API, Python client, or Sift CLI. ## Export data from the UI ### Export from a Run's overview page 1. Select **Runs** in the navigation, then search for the Run in the **Run name or description** box. 2. In the **Runs** table, click the Run. 3. Click **Export Data**. 4. In the **Channels** table, select the Channels you want to export. To export the entire Run, click **Select all Channels**. 5. Click **Next**. 6. Select a [file format](/documentation/reference/supported-file-formats#export-file-formats). 7. Optional: Select a [Channel name display](/documentation/reference/supported-file-formats#channel-name-display) option, a [file splitting](/documentation/reference/supported-file-formats#file-splitting) option, or a [Channel data grouping](/documentation/reference/supported-file-formats#channel-data-grouping) option. 8. Optional: Enable **Embed Channel Configs** to write each Channel's configuration into the exported file. A file exported this way can be re-imported into Sift with no manual configuration. See [Embedded Channel configurations](/documentation/reference/supported-file-formats#embedded-channel-configurations). 9. Click **Export**. ### Export from Explore Export from Explore is only available for Timeseries Panels. **Export restrictions**: Nested Calculated Channels cannot be exported and are excluded from the output. Relative Time mode is not supported for export. 1. In the Timeseries Panel toolbar, click **Export data**. 2. Select an [export option](/documentation/reference/explore-settings#export-data). 3. Optional: If you select **Advanced Export**, configure [Channel name display](/documentation/reference/supported-file-formats#channel-name-display), [file splitting](/documentation/reference/supported-file-formats#file-splitting), [Channel data grouping](/documentation/reference/supported-file-formats#channel-data-grouping), and [Embed Channel Configs](/documentation/reference/supported-file-formats#embedded-channel-configurations) in the **Export Data** dialog. 4. Click **Export**. ## Export using the REST API Sift provides two REST API mechanisms for exporting data. ### Data querying 1. Use [`POST /api/v2/data`](/api-reference/dataservice/getdata-1) to query specific Channels over a time window and receive the response immediately. ### Export to file 1. Use [`POST /api/v1/export`](/api-reference/exportservice/exportdata) to submit a background export job. 2. Use [`GET /api/v1/export/{jobId}/download-url`](/api-reference/exportservice/getdownloadurl) to retrieve the download link when the job is complete. ## Export using the Python client 1. Install the [official Python client](https://sift-stack.github.io/sift/python/latest/). 2. Configure the client with your [API key](/documentation/manage/set-up-api-access) and Sift URL. 3. Export data using the appropriate method for your use case. For code examples and full method references, see [Export data programmatically](/api/export/export-data-programmatically). ## Export using the Sift CLI Use `sift-cli export` to export data from the command line. See the [Sift CLI getting started guide](https://github.com/sift-stack/sift/blob/main/rust/crates/sift_cli/assets/docs/src/introduction.md) to learn more. ## Verify A notification confirms the background export has started. Track its progress in the **Jobs** menu. ## Reference * [File formats for import and export](/documentation/reference/supported-file-formats) # Understand Assets, Channels, and Runs Source: https://docs.siftstack.com/documentation/get-started/data-model Learn how Sift organizes data Sift organizes machine data around the way people work. You usually start with: * an [Asset](../ingest/stream/organize-streamed-data-into-assets-and-runs): the system, vehicle, or test article you are examining * one or more [Channels](/documentation/reference/channels-reference): the signals or measurements you care about * a [Run](/documentation/reference/runs-reference): the recording session, test, or mission where that data was captured This process lets you move from “what happened” to “when it happened” in a simple workflow. ## Workflows that connect Assets, Channels, and Runs ### 1. Pick the asset you want to investigate Think of an Asset as the thing you are working on: * a rocket stage * an aircraft * a manufacturing line * a robot or vehicle In Sift, an Asset groups data from the same system or test article so you can find everything related to it. ### 2. Choose the Channels that matter Channels are the individual measurements from that Asset: * temperature * pressure * speed * voltage * vibration When you [Explore](/documentation/analyze/analyze-a-run) data in Sift, you select Channels to see the exact signals you need for your workflow. ### 3. Open a Run to see the data in time A Run is the captured session of data from one or more Channels: * a single flight * a test stand cycle * a production batch * a mission segment Runs let you view the data in the time window where the event occurred. ## How the model helps your work * To troubleshoot a failure, choose the Asset, open the Run, and plot the Channels that show the problem. * To compare behavior, open two Runs for the same Asset and look at the same Channels side by side. * To validate a test campaign, review the Channels in a Run and confirm the data supports the result. * To share findings, send a link to the same Asset, Channels, and Run so everyone is looking at the same story. ## Simple relationship In practice, the workflow is: * find the **Asset** you care about, * select the **Channels** you want to inspect, * open the **Run** where that data was recorded. That is the core relationship in Sift’s data model, expressed as the steps you take every time you analyze machine data. # Glossary Source: https://docs.siftstack.com/documentation/get-started/glossary Definitions of common Sift concepts including Runs, Channels, Annotations, Campaigns, and data ingestion methods. The core concepts in Sift build on its telemetry data model of Assets, Channels, and Runs. The terms below describe the key objects used to analyze and review telemetry in Sift, workflow and analysis terms, and data ingestion methods. ## Core data model terms ### Asset A physical or virtual system that produces telemetry data in Sift. Assets organize data sources such as vehicles, test rigs, robots, or spacecraft so that telemetry can be associated with the correct system and analyzed consistently across Runs. See [Assets](/documentation/ingest/stream/organize-streamed-data-into-assets-and-runs). ### Channel An individual telemetry signal recorded from an Asset, typically represented as a time-series measurement such as temperature, voltage, or pressure. Channels are the fundamental data streams that users visualize and analyze. See [Channels](/documentation/reference/channels-reference). ### Calculated Channel A derived signal created from one or more Channels using mathematical or logical expressions. Calculated Channels let users generate new signals and insights without changing the original telemetry data. See [Calculated Channels](/documentation/transform/create-a-derived-signal). ### Run A defined time period during which telemetry is recorded from an Asset, such as a test, experiment, or operational session. Runs provide the primary time context for organizing and analyzing telemetry. See [Runs](/documentation/reference/runs-reference). ## Workflow and analysis terms ### Annotation A note attached to telemetry data to record observations, findings, or issues discovered during analysis. Annotations help teams capture insights directly alongside the data. See [Annotations](/documentation/reference/annotations-reference). ### Campaign A workspace that groups related Reports and Annotations into a coordinated review process. Campaigns help teams organize large analysis efforts and track progress across Runs or systems. See [Campaigns](/documentation/review/track-a-multi-run-review-campaign). ### Explore The main Sift workspace used to visualize and analyze telemetry data. Users plot Channels, compare Runs, and investigate behavior over time. See [Explore](/documentation/analyze/analyze-a-run). ### Panel A visualization container within Explore that displays telemetry data using a chart or table. Multiple panels allow users to compare signals or views side by side. See [Panels](/documentation/reference/explore-settings). ### Report A structured summary of analysis results. Reports help teams document findings and review telemetry behavior in a consistent format. See [Reports](/documentation/review/overview). ### Report Template A reusable structure for creating Reports. Templates standardize how analysis results are recorded and reviewed. See [Report Templates](/documentation/review/set-up-a-repeatable-review-checklist). ### Rule A defined condition that evaluates telemetry data to detect patterns, anomalies, or events automatically. Rules help teams identify important behavior in telemetry without manually scanning signals. See [Rules](/documentation/review/detect-deviations-automatically-using-rules). ### User-Defined Function (UDF) Custom logic written by users to transform or analyze telemetry data. UDFs allow teams to reuse calculations across Rules, Calculated Channels, or other analysis workflows. See [User-Defined Functions](/documentation/transform/reuse-expression-logic). ### Advanced Export A feature that exports telemetry data from Runs or Channels for use outside Sift. This allows teams to move data into other analysis tools or archives. See [Advanced Export](/documentation/export/export-data-from-a-file). ## Data import and ingestion ### Data files A method for importing data either programmatically or directly through the UI. Supported formats include CSV, Parquet, TDMS, HDF5, and ULog. See [Import data files](/documentation/ingest/data-import/import-data-from-a-file). ### Protobuf Ingestion A method for streaming telemetry data into Sift using Protocol Buffers (Protobuf) messages. This format enables efficient, structured transmission of telemetry data from external systems into Sift’s ingestion pipeline. See [Protobuf Ingestion](/documentation/reference/stream/protobuf-ingestion-reference). ### Ingestion Config Based Streaming A configuration that defines how telemetry data is streamed into Sift for a specific Asset. It specifies how incoming data is associated with the Asset and processed during ingestion. See [Ingestion Config Based Streaming](/documentation/reference/stream/ingestion-config-streaming-reference). ### Flow A processing step within an ingestion configuration that determines how incoming telemetry data is handled as it enters Sift. See [Flows](/documentation/reference/stream/ingestion-config-streaming-reference). # Navigate the Sift workspace Source: https://docs.siftstack.com/documentation/get-started/navigate Locate Sift's core sections, including Runs, Rules, and Reports, and understand how the navigation is organized. Sift is organized around a small set of core sections. Once you know where each one lives and what it does, you can move quickly through any workflow, from importing data to detecting anomalies and sharing results. ## The global navigation A left navigation, available from anywhere in Sift, lets you jump directly to other sections: * **Explore**: visualize and analyze telemetry * **Data sources**: Runs, Assets, Families * **Review**: Reports, Campaigns, Annotations * **Transform**: Calculated Channels, User-Defined Functions * **Automate**: Rules, Report Templates ## Explore Explore is Sift's main workspace for visualizing and analyzing telemetry data. When you open a Run, it opens in Explore, where you can add Panels, plot Channels, run calculations, and compare behavior across tests. Explore is where most hands-on analysis happens. Use it to investigate signals, identify patterns, and build the evidence behind your findings. * **Tutorial**: [Getting started with Explore](/tutorials/analyze/explore/tutorial-1) ## Data sources ### Runs The Runs section lists every time window of recorded telemetry in your workspace. Each Run represents a discrete session during which data was captured from an Asset (a test, a flight, an experiment, etc.). From the Runs list, you can browse and search for Runs by name or metadata, or open a Run to visualize it in Explore. **Workflows**: * [Analyze a Run](/documentation/analyze/analyze-a-run) * [Investigate a telemetry anomaly](/documentation/analyze/investigate-telemetry-anomaly) * [Compare signals over time](/documentation/analyze/compare-signals-over-time) ### Assets The Assets section shows the physical or virtual systems in your workspace that produce telemetry. An Asset groups together all the Runs, Annotations, User Groups, and Rules associated with a particular machine or system. Browse Assets to understand what data is available in your workspace and to find the Runs associated with a specific system. **Workflows**: * [Organize streamed data into Assets and Runs](/documentation/ingest/stream/organize-streamed-data-into-assets-and-runs) * [Organize resources with Metadata](/documentation/manage/organize-and-filter-resources-with-metadata) * [Monitor ingestion health](/documentation/ingest/monitor-ingestion-health) ### Families The Families section groups related Runs into a named baseline for comparison. Use a Family to compare new Runs against a historical spread in Explore, compute aggregate statistics such as mean and standard deviation across the group, and build Rules that flag when a new Run deviates from that statistical envelope. **Workflows**: * [Group Runs into a Family](/documentation/analyze/families/group-runs-into-a-family) * [Compare Runs visually against a Family baseline](/documentation/analyze/families/compare-runs-visually-against-a-family-baseline) * [Detect statistical deviations using Family Rules](/documentation/analyze/families/detect-deviations-from-a-historical-baseline) ## Review ### Reports Reports are structured summaries of how your Rules evaluated a Run. After a Rule runs against telemetry, you can generate a Report to capture what triggered, what the data showed, and what the current status is. Use Reports to communicate findings consistently across your team and to close the loop on issues you've identified. **Workflows**: * [Detect and review issues in a Run](/documentation/review/detect-and-review-issues-in-a-run) * [Set up a repeatable review checklist](/documentation/review/set-up-a-repeatable-review-checklist) * [Triage and close out flagged issues](/documentation/review/triage-and-close-out-flagged-issues) ### Campaigns The Campaigns section groups Reports from multiple Runs into a single workspace. Use a Campaign to track review progress across a test program and to filter Annotations across Runs by assignee, status, Asset, or Rule without opening each Report individually. **Workflows**: * [Campaigns: track a multi-Run review effort](/documentation/review/track-a-multi-run-review-campaign) * [Triage and close out flagged issues](/documentation/review/triage-and-close-out-flagged-issues) ### Annotations An Annotation is a time range linked to data that records an observation, finding, or issue discovered during analysis, such as a Rule violation or a manually flagged moment. The Annotations section provides a workspace-level view of every Annotation across all Runs, with filters by status, assignee, Asset, Run, or Rule. **Workflows**: * [Triage and close out flagged issues](/documentation/review/triage-and-close-out-flagged-issues) * [Detect and review issues in a Run](/documentation/review/detect-and-review-issues-in-a-run) * [Investigate a telemetry anomaly](/documentation/analyze/investigate-telemetry-anomaly) ## Transform ### Calculated Channels The Calculated Channels section is where you create and manage derived signals: new metrics built from one or more existing Channels using expressions. Calculated Channels let you define a computation once and reuse it across analyses. **Workflows**: * [Calculated Channels: create a derived signal](/documentation/transform/create-a-derived-signal) * [Reuse expression logic](/documentation/transform/reuse-expression-logic) * [Investigate a telemetry anomaly](/documentation/analyze/investigate-telemetry-anomaly) ### User-Defined Functions A User-Defined Function is a reusable CEL expression that can be called by name inside the expressions of Calculated Channels, Rules, and other User-Defined Functions. Define logic once, such as a threshold calculation or a normalization formula, and reuse it consistently across your workspace. **Workflows**: * [Reuse expression logic](/documentation/transform/reuse-expression-logic) * [Calculated Channels: create a derived signal](/documentation/transform/create-a-derived-signal) ## Automate ### Rules The Rules section is where you create and manage the logical conditions that automatically evaluate your telemetry. A Rule watches for a specific pattern (a threshold breach, an anomaly, a state transition, etc.) and flags it when found. From the Rules section, you can create new Rules, preview them against existing Runs, and manage versions as your detection logic evolves. **Workflows**: * [Detect deviations automatically using Rules](/documentation/review/detect-deviations-automatically-using-rules) * [Detect statistical deviations using Family Rules](/documentation/analyze/families/detect-deviations-from-a-historical-baseline) * [Get alerted when a limit is breached](/documentation/manage/get-alerted-when-a-limit-is-breached) ### Report Templates A Report Template saves a named group of Rules so you can apply a consistent set of checks to every Run automatically. When generating a Report, select the template instead of individual Rules, and Sift evaluates every Rule in the template in one step. **Workflows**: * [Set up a repeatable review checklist](/documentation/review/set-up-a-repeatable-review-checklist) * [Detect and review issues in a Run](/documentation/review/detect-and-review-issues-in-a-run) ## The Manage section Select your profile icon, then select Manage to reach this section. The Manage section covers workspace administration: API keys for programmatic access to Sift, Access control for who can see and interact with data, Metadata definitions for organizing and filtering Runs and Assets, and Webhooks for outbound notifications on Rule events. The Manage section is primarily used by workspace administrators and is separate from the day-to-day analysis workflow. **Workflows**: * [Set up API access](/documentation/manage/set-up-api-access) * [Get alerted when a limit is breached](/documentation/manage/get-alerted-when-a-limit-is-breached) * [Organize resources with Metadata](/documentation/manage/organize-and-filter-resources-with-metadata) * [Recover failed ingestion data](/documentation/manage/identify-and-recover-failed-ingestion-data) * [Connect an Identity Provider (IdP)](/documentation/manage/connect-an-identity-provider) * [Manage user access](/documentation/manage/manage-user-access) * [Set up attribute-based access policies](/documentation/manage/set-up-data-access-governance) ## Account settings Select your profile icon to reach your account settings. Use this area to manage your personal preferences. # Create your first telemetry workflow Source: https://docs.siftstack.com/documentation/get-started/quickstart Quickly learn how to import your telemetry into Sift. By the end of this quickstart, you will be able to: * Access your workspace * Import telemetry * Analyze it in Explore multi-panel layout * Share insights with others ## Step 1: Access Sift To use Sift, you need an account in your organization's Sift instance. Your manager should provide access to either the public cloud or GovCloud environment. ## Step 2: Import data 1. Select **Runs** in the navigation, then select **Import Data**. 2. Download [this](https://drive.google.com/file/d/1_8MXmOcT2vLh1zXE6uThX-bYytN4XGBS/view?usp=sharing) CSV file and upload it into Sift. 3. In **Asset**, click **New**, and in **Asset name**, enter: ``` fl_quickstart_asset ``` 4. In **Run**, change the Run name (**rover.csv**) to ``` fl_quickstart_run ``` 5. Replace `fl` in `fl_quickstart_asset` and `fl_quickstart_run` with your initials. This helps avoid naming conflicts if others are doing this quickstart on the same Sift instance. 6. Click **Upload**, and then click **Close**. ## Step 3: Analyze data 1. In **Search**, enter the Run name. 2. In the results, click the run. 3. Click **Explore**. 4. Create the following three panels: 1. In **Channels**, click **battery\_charge**. 2. Click to add a new panel, then select **Timeseries**. 3. In **Channels**, under **motor\_a**, click the following two Channels: * **current** * **temperature** 4. Click , then select **Table**. 5. In **Channels**, click: * **battery\_charge**. * Under **motor\_a**, click the following two Channels: * **current** * **temperature** 5. Create a multi-panel layout: 1. Click and hold the **Table 1** tab then drag it to the bottom of the screen. Once you see the bottom area highlight, let go to place it there. 2. Click and hold the **Timeseries 2** tab then drag it to the bottom right corner of the screen. 3. Right-click the **Timeseries 1** tab and select **Split right**. 4. In **Channels**, **motor\_a**, click the following Channel: * **encoder** ## Step 4: Share data Share links can be sent to other Sift users. When they open the link, they will see Explore with the **exact same configuration**, making collaboration easier and more consistent. 1. Click **Share**. 2. Share the link. # What is Sift? Source: https://docs.siftstack.com/documentation/get-started/what-is-sift Learn the core concepts of the Sift data model. Sift helps teams working on complex machines move from raw telemetry to confident decisions faster. Sift is designed for users who need to make sense of high-frequency data from rockets, aircraft, robots, manufacturing systems, and other hardware platforms. Instead of starting from architecture, Sift starts from the work you need to do: * Connect your test or mission data * Explore what happened * Validate the results * Share findings with the people who need them. For teams working on high-value hardware, the hardest part is often not that the data exists but that the data is scattered, noisy, and hard to connect. Sift is built to help you: * Get the right telemetry in front of you * Follow the story inside your data * Make and share decisions with confidence * Move from disorder to traceable insight This is the user workflow that defines how Sift supports your work every day. ## Common workflows ### 1. Understand a test run or mission quickly When you load a run, Sift presents the data in ways that match your workflow: * View the same channels and signals that matter to your system * Overlay sensor traces and events to see correlations * Jump from summary views into the exact time window where something changed This makes it easier to answer questions like: * “Why did this channel spike at this point?” * “Did the anomaly happen before or after the subsystem reboot?” * “How did this run compare to the previous one?” ### 2. Investigate issues across assets and subsystems Sift helps you trace problems through multiple sources of truth: * Compare runs side by side * Search for the same failure patterns across tests * Link alarms, anomalies, and rule results back to the data that caused them The goal is to keep your focus on the investigation, not on managing separate tools. ### 3. Review and validate results with stakeholders Your review workflow can include: * Automated checks and rule-based review for common issues * Human review for exceptions, anomalies, and unexpected behavior * Shared views so engineers, analysts, and managers see the same timeline This is especially useful when you need to confirm that a flight test, production campaign, or system checkout is ready to move forward. ### 4. Share findings and keep work repeatable Once you’ve found the answer, Sift makes it easier to: * Share a link to the same data view * Preserve the context and filters used during the investigation * Reuse the same analysis patterns on future tests That means your team can work consistently and avoid repeating the same setup steps. ## Platform Sift is composed of **three** architectural layers: **infrastructure**, **applications**, and **governance** (designed to work independently or together, depending on your needs). These layers are modular and support flexible deployment models, including managed SaaS, hybrid (on-prem compute with cloud storage), or fully on-premise for classified environments. ### Infrastructure layer Purpose-built ingestion and storage system for structured hardware telemetry. * **Ingestion**: Real-time ingestion of structured (Protobuf, Influx, etc.) and unstructured (logs, video, etc.) data from test stands, flight systems, or CI pipelines. * **Streaming stateful analysis**: Processes data on the fly using configurable rules and statistical operators, enabling anomaly detection, filtering, and derived signal computation. * **Managed storage**: High-throughput, object-based storage optimized for high-cardinality datasets. Supports schema evolution and time-aligned access. ### Application layer User-facing tools for analysis, review, and collaboration. * **Root cause analysis**: Compare test runs, inspect anomalies, correlate data across subsystems, no code required. * **Data review**: Run automated data checks using rule-based review pipelines, customizable by subsystem or mission phase. * **Visualization and dashboards**: Build plots and timelines across channels, overlay data, and share via links, integrated or using tools like Grafana. * **Data-driven manufacturing**: Capture lineage and test context at the part or component level, supporting traceability and regulatory compliance. ### Governance layer Controls system-level behavior, access, and performance. * **Role-based access control (RBAC)**: Granular user and group-based permissions across assets, data, and features. * **Query optimization and load balancing**: Manages query workloads to ensure stability during peak usage or live operations. * **Agentic interfaces (planned)**: Adds support for future LLM-based interfaces that operate on versioned, explainable metadata (for example, genealogy, dimensions). # Automate telemetry review with Sift Source: https://docs.siftstack.com/documentation/home Ingest telemetry. Define checks. Automate reviews. Create a single source of truth for your telemetry by uploading files or connecting a live data stream. Upload a telemetry file to create a Run and start analyzing your data. Select the streaming method that fits your situation. Send telemetry to Sift using Python. Verify data flow, troubleshoot ingestion failures, and track pipeline performance. Explore your telemetry interactively to plot signals, spot patterns, and investigate anomalies. Open a Run in Explore, plot Channels, build a multi-panel workspace to analyze and share telemetry. Isolate unusual signal behavior, compare related Channels, and identify the root cause of an anomaly. Use Live mode in Explore to monitor telemetry as it streams into Sift. Plot multiple Channels in the same workspace to identify correlations, trends, and dependencies between signals. Compare a new Run against a baseline Run to identify regressions and validate expected behavior. Apply the same Channel layout and settings to every new Run without rebuilding your workspace from scratch. Derive new signals from your raw telemetry using expressions, without modifying the original data. Compute a new signal from one or more existing Channels using a Calculated Channel expression. Define expression logic once and reference it across Calculated Channels, Rules, and User-Defined Functions. Automatically detect issues in your telemetry and track them to resolution. Write a Rule that flags conditions in your telemetry so deviations are caught automatically on every Run. Create a reusable checklist of Rules that runs against every new Run automatically. Review a Run to investigate and close issues. Assign, update, and resolve Annotations to drive a review to completion. Organize Reports from multiple Runs into a Campaign and track overall review progress. Create a named group of related Runs to use as a comparison baseline, statistical reference, and automated detection source. Write a Rule that automatically flags when a new Run falls outside the statistical envelope of your reference Runs. Overlay Family members on a shared aligned time axis in Explore to inspect variance, identify outliers, and compare a new Run against the historical spread. Pull your telemetry out of Sift to power external dashboards, analysis tools, and custom pipelines. Download telemetry from a Run as CSV, Parquet, or Sun (WinPlot) for use in external tools or archiving. Get telemetry from Sift into MATLAB using the Python client or the REST API. Install the Sift FlexLogger plugins to stream Channel data live or upload TDMS files after a run. Connect Sift as a Grafana data source to build persistent dashboards for live monitoring and historical analysis. Govern who can access your telemetry data, manage users and permissions, and keep your workspace organized. Set up a webhook to receive notifications in an external system when a Rule is violated or resolved during live data ingestion. Define a structured taxonomy using Metadata keys to organize, categorize, and filter resources including Runs, Campaigns, and Annotations across your workspace. Invite users, manage their status, and organize them into groups to control access to Sift. Use Attribute-Based Access Control (ABAC) to control access to Sift resources. Configure an external Identity Provider to manage users and groups in Sift using SCIM push provisioning. # Import data from a file Source: https://docs.siftstack.com/documentation/ingest/data-import/import-data-from-a-file Import a telemetry file into Sift and start analyzing your data. After completing this workflow, you can upload a local file to Sift and have its Channels available for investigation in Explore. ## Before you begin * Choose the import method that fits your use case. Supported file types vary by method. * Your file includes a timestamp column in a [supported timestamp format](/documentation/reference/supported-file-formats#timestamp-formats). * You know which Asset and Run the data belongs to, or are prepared to create new ones. ## How data file import works Importing a file creates a Run under an [Asset](/documentation/ingest/stream/organize-streamed-data-into-assets-and-runs) in Sift. An Asset represents the system that generated the data, such as a vehicle or test rig. A [Run](/documentation/reference/runs-reference) is a single data collection session. During import, you map the file's timestamp column and data columns to Channels. You do not need to import every column, only map the ones you intend to analyze. You can use an existing Asset and Run or create new ones during import. If a mapping is wrong or a timestamp format is misidentified, you can archive the Run and reimport without affecting the Asset or other Runs. **Embedded Channel configurations**: If a CSV or Parquet file contains an embedded Channel configuration, written by Sift when [Embed Channel Configs](/documentation/export/export-data-from-a-file) is enabled on export, or added to the file manually, Sift detects it automatically and pre-fills the Channel Configuration table, including enum and bit field editors. See [Embedded Channel configurations](/documentation/reference/supported-file-formats#embedded-channel-configurations). ## Import a file using the UI 1. Select **Runs** in the navigation, then select **Import data**. 2. Select your file. 3. Configure the import settings. See [Import file settings](/documentation/reference/supported-file-formats#import-file-settings) for a full description of each setting. 4. Click **Upload**. ## Import a file using the REST API 1. Send a configuration request to the [`CreateDataImportFromUpload`](/api-reference/dataimportservice/createdataimportfromupload) endpoint with your [API key](/documentation/manage/set-up-api-access). The endpoint accepts a format-specific configuration object depending on your file type. * **Remote URL**: To import a file from a remote URL instead of uploading it directly, use the [`CreateDataImportFromUrl`](/api-reference/dataimportservice/createdataimportfromurl) endpoint. 2. Upload the file using the returned `uploadUrl`. 3. Optional: Verify the upload using the returned `dataImportId`. **Embedded Channel configurations**: To import using an embedded Channel configuration, set `csvConfig.useEmbeddedConfig` or `parquetConfig.flatDataset.useEmbeddedConfig` to `true`. Parquet also requires `footerOffset` and `footerLength`. See [Embedded Channel configurations](/documentation/reference/supported-file-formats#embedded-channel-configurations). Sift queues the import server-side the moment the request is received. A client-side timeout on the upload request does not indicate the import failed or was not received. To confirm whether an import actually failed, poll the import status and check for `DATA_IMPORT_STATUS_FAILED`. Any other status means the import is queued or in progress. See [DataImportStatus](/api/reference/protocol-buffers/data_imports#dataimportstatus) for more information. **Data import configuration**: When `useEmbeddedConfig` is set, Sift ignores any other data import configuration you provide and uses only the embedded Channel configuration. ## Import a file using the Python client 1. Install the [Python client](https://sift-stack.github.io/sift/python/latest/). 2. Configure the client with your [API key](/documentation/manage/set-up-api-access) and Sift URL. 3. Upload the file using the appropriate upload service for your format. For code examples, see the [Sift public repository](https://github.com/sift-stack/sift/tree/main/python/examples/data_import). ## Import a file using the Sift CLI Use the `sift-cli import` command to import a file from the command line. See the [Sift CLI getting started guide](https://github.com/sift-stack/sift/blob/main/rust/crates/sift_cli/assets/docs/src/introduction.md) to learn more. ## Verify Your file appears as a Run under the selected Asset. Open the Run in [Explore](/documentation/reference/explore-settings) to confirm the Channels loaded correctly. ## Reference * [File formats for import and export](/documentation/reference/supported-file-formats) # Monitor ingestion health Source: https://docs.siftstack.com/documentation/ingest/monitor-ingestion-health Use sift_app to verify data flow, troubleshoot ingestion failures, and track pipeline performance. After completing this workflow, you can confirm your data is arriving in Sift, identify records that failed to ingest, and track ingestion rates over time using **sift\_app**, a built-in system Asset. ## Before you begin * You are familiar with how [Sift organizes data into Assets, Channels, and Runs](/documentation/get-started/data-model). ## How ingestion monitoring works **sift\_app** is a built-in system Asset that provides real-time telemetry about your data pipeline's performance and stability. It surfaces internal metrics through the same infrastructure you use for your own data, allowing you to build dashboards and set up alerts for specific Channels using familiar Sift tools. **sift\_app** is organized into four subsections, each representing a different layer of the ingestion journey: * [**data\_import**](/documentation/reference/asset-settings#data_import): Metrics for data imported via file upload. Use this to confirm an import completed successfully or to understand why it failed. * [**dlq\_ingestion**](/documentation/reference/asset-settings#dlq_ingestion): Metrics for records that failed to ingest. Use this if data is not appearing in Sift as expected. * [**ingest\_grpc**](/documentation/reference/asset-settings#ingest_grpc): Metrics for data streamed through the gRPC APIs. Use this to confirm data is actively flowing into Sift. * [**stream**](/documentation/reference/asset-settings#stream): Metrics for the Rust `sift-stream` client. Use this to monitor client-side ingestion behavior. ## Access sift\_app 1. Select **Assets** in the navigation. 2. In the **Asset name** search box, enter **sift\_app**. 3. In the **Assets** table, click **sift\_app**. 4. Click **Explore**. ## Monitor ingestion metrics Once in Explore, the **sift\_app** subsections appear in the **Channels** tab. 1. Expand the subsection you want to monitor. 2. Click a Channel to plot it. 3. Review the plot to understand the current state of that part of your pipeline. ## Next steps * To review and reingest data that failed, see [Recover failed ingestion data](/documentation/manage/identify-and-recover-failed-ingestion-data). ## Reference * [Assets settings](/documentation/reference/asset-settings) # Choose a streaming method Source: https://docs.siftstack.com/documentation/ingest/stream/choose-a-streaming-method Select the streaming method that fits your situation Sift supports several streaming methods. Each method suits a different starting point. Use the table below to match your situation to the right method, then follow the link to get started. | If you want to… | Use… | | -------------------------------------------- | ------------------------------------------------------------------------------------------------------ | | Get started quickly from Python code | [Python client library](/documentation/ingest/stream/stream-your-first-telemetry-data-with-python) | | Stream from any language using gRPC | [Ingestion-config streaming](/documentation/ingest/stream/stream-telemetry-from-a-running-application) | | Send data from an existing protobuf pipeline | [Protobuf ingestion](/documentation/reference/stream/protobuf-ingestion-reference) | | Send arbitrary JSON quickly without a schema | [Schemaless ingestion](/documentation/reference/stream/schemaless-ingestion-reference) | | Reuse an existing Influx setup | [Influx Line Protocol](/documentation/reference/stream/influx-line-protocol-reference) | | Import historical files instead of streaming | [Import](/documentation/ingest/data-import/import-data-from-a-file) | ## Method comparison | Method | Protocol | Schema required | Best for | | -------------------------- | ---------- | ------------------------ | -------------------------------------------------- | | Python client library | gRPC | Yes (defined in code) | New Python projects; fastest onboarding path | | Ingestion-config streaming | gRPC | Yes (registered via API) | Any language; high-throughput production streaming | | Protobuf ingestion | gRPC | Yes (compiled .proto) | Teams with an existing protobuf telemetry pipeline | | Schemaless ingestion | REST | No | Quick experiments; low-volume or ad-hoc data | | Influx Line Protocol | HTTP | No | Teams already using an Influx client | | Import | REST/HTTPS | No | Historical data; batch uploads from files or URLs | ## Related topics * [Stream your first telemetry data with Python](/documentation/ingest/stream/stream-your-first-telemetry-data-with-python) * [Stream telemetry from a running application](/documentation/ingest/stream/stream-telemetry-from-a-running-application) * [Client library reference](/documentation/reference/stream/client-library-reference) # Continue streaming across multiple Runs Source: https://docs.siftstack.com/documentation/ingest/stream/continue-streaming-across-multiple-runs Stream data across restarts or separate processes After completing this topic, you can retrieve existing Runs by client key or name and resume streaming data into them across restarts or separate processes. ## Before you begin * You have already created at least one Run. See [Organize streamed data into Assets and Runs](/documentation/ingest/stream/organize-streamed-data-into-assets-and-runs). * You have a Sift API key and base URL. See [Authentication](/documentation/manage/set-up-api-access). ## How Run retrieval works When a process restarts or a new process needs to stream into an existing Run, you can look up the Run by its `client_key` or other criteria instead of storing the server-assigned `run_id` externally. Sift provides two retrieval methods: * `RunService.GetRun`: retrieves a single Run by its exact `run_id`. Use this when you already have the ID. * `RunService.ListRuns`: searches for Runs using filter criteria such as `client_key` or `name`. Use this when you need to find a Run without a stored ID. ## Retrieve and resume a Run ### Step 1: Look up a Run by client key Use `RunService.ListRuns` with a filter on `client_key` to find a specific Run. ```bash curl theme={null} curl -G \ -H "Authorization: Bearer $API_TOKEN" \ -d "filter=client_key=='example_client_key'" \ $SIFT_REST_URL/api/v2/runs ``` ```bash grpcurl theme={null} grpcurl -H "authorization: Bearer $API_TOKEN" -d @ $SIFT_GRPC_URL:$PORT_NUM sift.runs.v2.RunService/ListRuns < Other available search parameters are documented in [ListRunsRequest](/api/reference/protocol-buffers/runs#listrunsrequest). ### Step 2: Include the Run ID in subsequent ingestion requests Once you have the `run_id`, include it in your `IngestWithConfigDataStreamRequest` to continue associating new data with that Run. ### Step 3: Update a Run To modify an existing Run (for example, to set its `stop_time`), use `RunService.UpdateRun`. See [UpdateRunRequest](/api/reference/protocol-buffers/runs#updaterunrequest) for the available fields. ## Verify the result After streaming additional data into the Run, open Sift and navigate to the asset. The Run should show updated data covering the full time range across all streaming sessions. ## Next steps * [Organize streamed data into Assets and Runs](/documentation/ingest/stream/organize-streamed-data-into-assets-and-runs) * [Stream telemetry from a running application](/documentation/ingest/stream/stream-telemetry-from-a-running-application) ## Reference * [Run API reference](/api/reference/protocol-buffers/runs#run) * [RunService reference](/api/reference/protocol-buffers/runs#runservice) * [ListRunsRequest](/api/reference/protocol-buffers/runs#listrunsrequest) * [UpdateRunRequest](/api/reference/protocol-buffers/runs#updaterunrequest) * [Runs reference](/documentation/reference/runs-reference) # Stream live telemetry Source: https://docs.siftstack.com/documentation/ingest/stream/index Choose a method to send real-time telemetry data from your application to Sift. Send time-series telemetry from your application to Sift in real time. ## Before you begin All streaming methods require an API key and the Sift URL for your environment. See [Authentication](/documentation/manage/set-up-api-access). ## What do you want to do? * **[I want to send telemetry from Python](/documentation/ingest/stream/stream-your-first-telemetry-data-with-python)**: Install the Python client library and stream sensor data to Sift quickly. * **[I want to send telemetry from an existing service](/documentation/ingest/stream/stream-telemetry-from-a-running-application)**: Define an ingestion config and stream structured data over gRPC from any application. * **[I already have protobuf data](/documentation/reference/stream/protobuf-ingestion-reference)**: Register your protobuf schema and stream serialized messages directly to Sift. * **[I want to send JSON quickly](/documentation/reference/stream/schemaless-ingestion-reference)**: POST JSON to Sift over REST without pre-registering a schema. * **[I already use Influx](/documentation/reference/stream/influx-line-protocol-reference)**: Point any Influx client at Sift using your API key as the authentication token. * **[I need help troubleshooting](/documentation/reference/stream/streaming-error-reference)**: Diagnose common reasons telemetry does not appear in Sift. ## Choose a method Not sure which method fits your situation? See [Choose a streaming method](/documentation/ingest/stream/choose-a-streaming-method) for a side-by-side comparison. # Organize streamed data into Assets and Runs Source: https://docs.siftstack.com/documentation/ingest/stream/organize-streamed-data-into-assets-and-runs Associate your streamed telemetry with Runs After completing this topic, you can create a Run and associate your streamed telemetry with it so that your data is grouped into a named, time-bounded capture in Sift. ## Before you begin * You have a Sift API key and base URL. See [Authentication](/documentation/manage/set-up-api-access). * You are already streaming data to Sift, or you are setting up streaming for the first time. See [Stream telemetry from a running application](/documentation/ingest/stream/stream-telemetry-from-a-running-application). ## How Assets are created An [Asset](/documentation/reference/asset-settings) exists in Sift in one of two ways: * Sift creates it automatically the first time data arrives for its name, whether through streaming, file upload, Run creation, or an ingestion config. * You create it explicitly before any data exists, using the **New Asset** button on the Assets page or the `CreateAsset` call on the [Asset API](/api/reference/protocol-buffers/assets). See [Create an asset](/documentation/reference/asset-settings#create-an-asset). Either way, data ingested for an existing Asset name attaches to that Asset rather than creating a duplicate. ## How Runs work A [Run](/documentation/reference/runs-reference) is a distinct grouping of time-series data captured from one or more [Assets](/documentation/ingest/stream/organize-streamed-data-into-assets-and-runs). By organizing telemetry into Runs, you can isolate specific events, tests, or missions, and investigate patterns, assess performance, and diagnose anomalies within a contextual timeframe. The [Run API](/api/reference/protocol-buffers/runs) supports the following fields: * `start_time`, `stop_time`—the time window of the Run. * `asset_ids`—one Run can span multiple assets. * `duration`—computed from `stop_time - start_time`, or ongoing if `stop_time` is not set. The general workflow is: 1. Optional: [create the Asset](/documentation/reference/asset-settings#create-an-asset). If it does not exist, Sift creates it when data first arrives. 2. Create a Run. 3. Stream data for an asset, including the Run ID in each request. 4. View the Run in Sift. ## Create a Run and associate it with streamed data ### Step 1: Create a Run Call `RunService.CreateRun`. The response returns a `CreateRunResponse` containing a `Run` with a `run_id`. Save the `run_id`; you will include it in your ingestion requests. **Client keys** The `Run` message has an optional `client_key` field that lets you assign a unique identifier to the Run. Although optional, it is recommended because it makes querying runs more convenient. A `client_key` can only be set once, at creation or on the first update. ### Step 2: Associate data with the Run There are two ways to associate a Run with asset data. **Manual association (recommended)** Include the `run_id` in each ingestion request. For ingestion-config-based streaming, add it to the `IngestWithConfigDataStreamRequest`: ```protobuf theme={null} IngestWithConfigDataStreamRequest { ingestion_config_id: "", run_id: "", flow: "", timestamp: , channel_values: [...], } ``` This ensures that the asset data in each request is associated with the specified Run. **Retrieving a Run ID** If the Run ID is not available, query your runs first. See [Continue streaming across multiple runs](/documentation/ingest/stream/continue-streaming-across-multiple-runs) for how to retrieve runs by `client_key`. **Automatic association** Call `RunService.CreateAutomaticRunAssociationForAssets` to associate a Run with specific assets in advance. Data arriving for those assets will automatically associate with the Run; you do not need to include the `run_id` in each ingestion request. **Non-standard workflow** Automatic association is not the standard workflow. If you use it, do not include the `run_id` in your `IngestWithConfigDataStreamRequest` for the associated assets. If one of the specified assets already has an ongoing Run (a Run with no `stop_time`), the endpoint will return an error. ## Verify the result After streaming, open Sift and navigate to the asset you streamed data for. You should see: * The Run listed with its name and start time. * Channel data visible within the Run's time window in Explore. ## Next steps * [Continue streaming across multiple runs](/documentation/ingest/stream/continue-streaming-across-multiple-runs) * [Stream telemetry from a running application](/documentation/ingest/stream/stream-telemetry-from-a-running-application) ## Reference * [Run API reference](/api/reference/protocol-buffers/runs#run) * [RunService reference](/api/reference/protocol-buffers/runs#runservice) * [Runs overview](/documentation/reference/runs-reference) * [Assets overview](/documentation/ingest/stream/organize-streamed-data-into-assets-and-runs) * [Ingestion config streaming reference](/documentation/reference/stream/ingestion-config-streaming-reference) # Stream telemetry from a running application Source: https://docs.siftstack.com/documentation/ingest/stream/stream-telemetry-from-a-running-application Stream structured telemetry over gRPC with an ingestion config After completing this topic, you can stream structured telemetry from any application to Sift over gRPC using an ingestion config. ## Before you begin * You have a Sift API key and base URL. See [Authentication](/documentation/manage/set-up-api-access). * You have a gRPC client for your language. See [Generate a client with buf](/api/clients/generate-a-client-with-buf). * Your application can call gRPC endpoints. ## How ingestion config streaming works Ingestion-config-based streaming separates schema registration from data transmission. You register the structure of your telemetry once (the Asset, flows, and Channels) using `IngestionConfigService.CreateIngestionConfig`. After that, you stream compact messages that reference the config by ID, which reduces packet size and improves throughput. A **flow** is a named group of Channels whose values are sent together in one request. Every request references a specific flow by name, and the Channel values in that request must match the order of channels defined in that flow. ## Stream telemetry to Sift ### Step 1: Create an ingestion config Send a `CreateIngestionConfigRequest` to `IngestionConfigService.CreateIngestionConfig`. This registers your asset, flows, and channels. ```protobuf theme={null} message CreateIngestionConfigRequest { string asset_name = 1 [(google.api.field_behavior) = REQUIRED]; repeated FlowConfig flows = 2; string organization_id = 3 [(google.api.field_behavior) = OPTIONAL]; string client_key = 4 [(google.api.field_behavior) = OPTIONAL]; } ``` **Client keys** Set `client_key` to a unique string you control. This lets you look up the config later without storing the server-assigned ID. Although optional, it is strongly recommended. The response returns an `ingestion_config_id`. Save this value; you will include it in every data request. ### Step 2: Define your flows and channels Each `FlowConfig` names a group of channels that are sent together. ```protobuf theme={null} message FlowConfig { string name = 1 [(google.api.field_behavior) = REQUIRED]; repeated ChannelConfig channels = 2; } message ChannelConfig { string name = 1 [(google.api.field_behavior) = REQUIRED]; string component = 2; string unit = 3; string description = 4; sift.common.type.v1.ChannelDataType data_type = 5 [(google.api.field_behavior) = REQUIRED]; repeated sift.common.type.v1.ChannelEnumType enum_types = 6; repeated sift.common.type.v1.ChannelBitFieldElement bit_field_elements = 7; } ``` **Channel ordering** The order of channels in a `FlowConfig` must be preserved exactly when you send channel values in a data request. Sift identifies which channel each value belongs to by position. Sending values out of order will cause errors or attribute data to the wrong channel. If you have data for some channels in a flow but not others, send `google.protobuf.Empty` in the position of the missing channel to preserve ordering. ### Step 3: Create a Run A [Run](/documentation/reference/runs-reference) groups the data you stream into a named, time-bounded capture. Creating a Run is strongly recommended; without a `run_id` in your ingestion requests, streamed data will not be organized into a Run and will not appear in Sift's Runs view. To create one, call `RunService.CreateRun` and save the returned `run_id`. ### Step 4: Stream data For each data point, construct an `IngestWithConfigDataStreamRequest` and send it to `IngestService.IngestWithConfigDataStream`. ```protobuf theme={null} message IngestWithConfigDataStreamRequest { string ingestion_config_id = 1; string flow = 2; google.protobuf.Timestamp timestamp = 3; repeated IngestWithConfigDataChannelValue channel_values = 4; string run_id = 5; bool end_stream_on_validation_error = 6; string organization_id = 7; } ``` | Field | Description | | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | | `ingestion_config_id` | The ID returned when you created the ingestion config. | | `flow` | The name of the flow this request sends data for. | | `timestamp` | The timestamp for all channel values in this request. | | `channel_values` | Ordered list of values matching the channel order in the flow definition. | | `run_id` | Strongly recommended. Include this in every request to associate data with a Run. Omitting it will cause streamed data to not appear in Sift's Runs view. | | `end_stream_on_validation_error` | Set to `true` only during development. Do not use in production; it severely impacts performance. | | `organization_id` | Optional unless your user belongs to multiple organizations. | **Validation and performance** When `end_stream_on_validation_error` is `false`, any server-side errors appear in Sift's Data Processing dashboard (`https://app.siftstack.com/manage/data-processing`). Do not set this flag to `true` in production. ### Step 5: Add flows to an existing ingestion config To add new flows after creation, send a `CreateIngestionConfigFlowRequest` to `IngestionConfigService`. Adding flows is backwards compatible. Do not modify or remove existing flows or channels. ## Verify the result After streaming, open Sift and navigate to the asset you specified in `asset_name`. You should see: * The asset listed under your organization. * If you created a Run, the Run appears with data for the channels you streamed. * Any server-side validation errors appear in the Data Processing dashboard. ## Next steps * [Organize streamed data into Assets and Runs](/documentation/ingest/stream/organize-streamed-data-into-assets-and-runs) * [Continue streaming across multiple runs](/documentation/ingest/stream/continue-streaming-across-multiple-runs) * [Stream your first telemetry data with Python](/documentation/ingest/stream/stream-your-first-telemetry-data-with-python) ## Reference * [Ingestion config streaming reference](/documentation/reference/stream/ingestion-config-streaming-reference) * [Client library reference](/documentation/reference/stream/client-library-reference) * [Streaming error reference](/documentation/reference/stream/streaming-error-reference) * [RunService API](/api/reference/protocol-buffers/runs#runservice) * [IngestService API](/api/reference/protocol-buffers/ingest#ingestservice) # Stream your first telemetry data with Python Source: https://docs.siftstack.com/documentation/ingest/stream/stream-your-first-telemetry-data-with-python Send telemetry to Sift using Python. After completing this topic, you can send telemetry from a Python script to Sift and see your data appear in a Run. ## Before you begin * Python 3.x is installed. * You have a Sift API key, gRPC URL, and REST URL. See [Authentication](/documentation/manage/set-up-api-access). ## How ingestion config streaming works The Python client library uses ingestion-config-based streaming. When you define an `IngestionConfigFormPy`, Sift registers the schema of your telemetry (your Asset, Flows, and Channels) the first time you connect. On subsequent connections with the same `client_key`, Sift reuses that schema so you do not need to re-register it. A Run groups the data you stream into a named, time-bounded capture. Runs are optional; you can stream data without one. ## Stream telemetry to Sift 1. Install the `sift-stack-py` package. ```bash theme={null} pip install sift-stack-py ``` 2. In your `main.py`, import the required modules. ```python theme={null} import asyncio import random from datetime import datetime, timezone from sift_client import SiftClient, SiftConnectionConfig from sift_client.sift_types import RunCreate from sift_stream_bindings import ( ChannelConfigPy, ChannelDataTypePy, ChannelValuePy, FlowConfigPy, FlowPy, IngestionConfigFormPy, TimeValuePy, ValuePy, ) ``` 3. Define a data source. The following example simulates sensor data by yielding a random float every 0.5 seconds for 60 seconds. ```python theme={null} async def data_source(): start = asyncio.get_event_loop().time() while asyncio.get_event_loop().time() - start < 60: await asyncio.sleep(0.5) yield datetime.now(timezone.utc), random.uniform(0, 10) ``` 4. Define the schema of your telemetry using `IngestionConfigFormPy` and `FlowConfigPy`. ```python theme={null} ASSET_NAME = "NostromoLV426" FLOW_NAME = "velocity-reading" CONFIG_KEY = "nostromo-lv-426-config-v1" flow_config = FlowConfigPy( name=FLOW_NAME, channels=[ ChannelConfigPy( name="mainmotor.velocity", unit="m/s", data_type=ChannelDataTypePy.Double, description="Main motor velocity", enum_types=[], bit_field_elements=[], ), ], ) ingestion_config = IngestionConfigFormPy( asset_name=ASSET_NAME, client_key=CONFIG_KEY, flows=[flow_config], ) ``` **Client keys** The `CONFIG_KEY` (client key) uniquely identifies your schema. Use the same key across restarts to reuse the registered schema. Adding new flows and channels over time is safe. Modifying existing flows or channels is not backwards compatible and will cause unexpected behavior. 5. Create a `SiftClient` and open a streaming session with a Run attached. ```python theme={null} async def main(): connection_config = SiftConnectionConfig( api_key="your-api-key", grpc_url="your-grpc-url", rest_url="your-rest-url", ) client = SiftClient(connection_config=connection_config) run = RunCreate(name=f"[{ASSET_NAME}].run", client_key=f"{CONFIG_KEY}.run") async with await client.async_.ingestion.create_ingestion_config_streaming_client( ingestion_config=ingestion_config, run=run, ) as ingest_client: async for timestamp, velocity in data_source(): await ingest_client.send( FlowPy( flow_name=FLOW_NAME, timestamp=TimeValuePy.from_timestamp_millis(int(timestamp.timestamp() * 1000)), values=[ ChannelValuePy(name="mainmotor.velocity", value=ValuePy.Double(velocity)), ], ) ) ``` **Runs are optional** Attaching a Run groups your data into a named capture. You can omit the `run` parameter if you want to stream data without grouping it into a Run. 6. Run the async entry point. ```python theme={null} if __name__ == "__main__": asyncio.run(main()) ``` ## Verify the result After the script finishes, open Sift and navigate to the asset (in our example, `NostromoLV426`). You should see: * The asset listed under your organization. * The Run you created, with a start time matching when the script ran. * Data for the channel(s) visible in Explore. ## Next steps * [Organize streamed data into Assets and Runs](/documentation/ingest/stream/organize-streamed-data-into-assets-and-runs) * [Stream telemetry from a running application](/documentation/ingest/stream/stream-telemetry-from-a-running-application) * [Choose a streaming method](/documentation/ingest/stream/choose-a-streaming-method) ## Reference * [Full Python code example](https://github.com/sift-stack/sift/tree/main/python/examples/ingestion-tutorial) * [sift\_client documentation](https://sift-stack.github.io/sift/python/latest/reference/sift_client/) * [sift-stack-py on PyPI](https://pypi.org/project/sift-stack-py/) * [Ingestion config streaming reference](/documentation/reference/stream/ingestion-config-streaming-reference) * [Client library reference](/documentation/reference/stream/client-library-reference) # Open Explore with a dynamic URL Source: https://docs.siftstack.com/documentation/integrate/open-explore-with-a-dynamic-url Construct a URL with query parameters to open Explore with Runs or Assets, Channels, Panel type, and an optional time range preloaded. After completing this workflow, you can open Explore with telemetry data preloaded by sharing or navigating to a URL that specifies Runs or Assets, Channels, Panel type, and an optional time range, without any manual setup in the interface. ## Before you begin * You must have access to an active Sift instance and know its domain name. * You need the names or UUIDs of the Runs, Assets, or Channels you want to load. ## How it works A dynamic URL is a link that opens Explore with specific data preloaded. You construct it by adding query parameters to the `/explore` route that define which Runs or Assets, Channels, Panel type, and time range to load. When a user navigates to the URL, Explore opens with that data already selected, with no manual setup required. For the full URL structure and supported parameters, see [URL structure](/documentation/reference/explore-settings#url-structure) and [URL parameters](/documentation/reference/explore-settings#url-parameters). For example, the following dynamic URL opens a Timeseries Panel with a single Channel on a single Run: ``` https://{domainName}/explore \ ?method=single \ &runs=runName \ &channels=channelName \ &panelType=timeseries ``` Dynamic URLs are constructed manually and let you define exactly what data loads on arrival. If you are already working in Explore, click **Share**, then **Copy** to capture the current workspace state instead. See [Share](/documentation/reference/explore-settings#share). ## Create a dynamic URL 1. Start with your base URL: ``` https://{domainName}/explore?method=single ``` 2. Append parameters for the Runs or Assets you want to load. You can use names, UUIDs, or a mix: ``` &runs=my-test-run &assetId=5161a578-c3f2-4ecb-8ea9-ae6fcbf3b3f0 ``` Run and Asset parameters can be combined in the same URL. 3. Append the Channels you want to plot. Add an axis or role prefix if needed: ``` &channels=temperature,pressure &channels=L1:temperature,R1:pressure ``` Channel names are matched case-insensitively. If a name cannot be resolved, a warning appears and remaining Channels still load. **UUID limitation**: Calculated Channel UUIDs don't resolve through `channels`, `channelId`, or `channelIds`, because Calculated Channels aren't persisted to a Run's Channel list the same way raw Channels are. Add a Calculated Channel manually in Explore instead of passing its UUID in a dynamic URL. 4. Set the Panel type if you want something other than the default Timeseries Panel: ``` &panelType=histogram ``` 5. Optionally, define a time range: ``` &startTime=2024-05-26T13:59:28.569Z \ &endTime=2024-05-26T14:02:52.232Z ``` 6. Join all parameters into a single continuous string with no spaces or backslashes, and share or navigate to the URL. ## Verify Navigate to the constructed URL. Confirm that the expected Runs or Assets, Channels, and Panel type load automatically. If a name cannot be resolved, a warning appears in Explore and the remaining selections still load. ## Examples ### Data source selection #### Run by name Selects a Run by name and plots two Channels. ``` https://app.siftstack.com/explore \ ?method=single \ &runs=my-test-run \ &channels=temperature,pressure ``` #### Asset by name with axis configuration Selects an Asset by name and assigns Channels to different Y-axes. ``` https://app.siftstack.com/explore \ ?method=single \ &assets=my-asset \ &channels=L1:temperature,R1:pressure ``` #### Mixed Run and Asset selection Pre-selects multiple Runs and a single Asset. Run and Asset parameters can be combined, and multiple Runs can be provided as a comma-separated list. ``` https://app.siftstack.com/explore \ ?method=single \ &runIds=8bfc7a2a-de0c-402c-bec1-089f4a69f128,2fd5e1f9-d185-4f18-a31d-8f2aee20ef17 \ &assetId=5161a578-c3f2-4ecb-8ea9-ae6fcbf3b3f0 \ &panelType=timeseries ``` #### Mixed UUIDs and names Specifies a Run by UUID and Channels using both a name and a UUID with an axis prefix. ``` https://app.siftstack.com/explore \ ?method=single \ &runs=8bfc7a2a-de0c-402c-bec1-089f4a69f128 \ &channels=temperature,L2:8dad764f-fda2-4784-9132-ddc616df46c1 ``` ### Panel types #### Timeseries with mixed axes Plots Channels on different Y-axes using axis prefixes. For prefix syntax, see [Channel axis assignment](/documentation/reference/explore-settings#channel-axis-assignment). ``` https://app.siftstack.com/explore \ ?method=single \ &runId=8bfc7a2a-de0c-402c-bec1-089f4a69f128 \ &assetIds=5161a578-c3f2-4ecb-8ea9-ae6fcbf3b3f0 \ &panelType=timeseries \ &channelIds=L1:df2cba99-abc2-4b36-bd16-e615b7682ace,L2:8dad764f-fda2-4784-9132-ddc616df46c1 ``` #### Table view Opens the Table Panel and evaluates selected Channels at the timestamp defined by `startTime`. ``` https://app.siftstack.com/explore \ ?method=single \ &runId=8bfc7a2a-de0c-402c-bec1-089f4a69f128 \ &panelType=table \ &channels=df2cba99-abc2-4b36-bd16-e615b7682ace,8dad764f-fda2-4784-9132-ddc616df46c1 \ &startTime=2024-05-26T14:00:00.000Z ``` #### Histogram Opens the Histogram Panel for a single Channel. If more than one Channel is provided, the first compatible Channel is used. For more on Channel compatibility by Panel type, see [Channel selection by Panel type](/documentation/reference/explore-settings#channel-selection-by-panel-type). ``` https://app.siftstack.com/explore \ ?method=single \ &runId=8bfc7a2a-de0c-402c-bec1-089f4a69f128 \ &panelType=histogram \ &channels=temperature ``` #### FFT Opens the FFT Panel for a single numeric Channel. ``` https://app.siftstack.com/explore \ ?method=single \ &runId=8bfc7a2a-de0c-402c-bec1-089f4a69f128 \ &panelType=fft \ &channels=vibration ``` #### Metrics Opens the Metrics Panel with several numeric Channels. ``` https://app.siftstack.com/explore \ ?method=single \ &runId=8bfc7a2a-de0c-402c-bec1-089f4a69f128 \ &panelType=metrics \ &channels=voltage,temperature,pressure ``` #### Scatter Plot with Channel roles Assigns Channels to the X-axis, Y-axis, and color using role prefixes. The color Channel renders with a Viridis gradient by default. For the full list of supported role prefixes, see [Scatter Plot Channel roles](/documentation/reference/explore-settings#scatter-plot-channel-roles). ``` https://app.siftstack.com/explore \ ?method=single \ &runId=8bfc7a2a-de0c-402c-bec1-089f4a69f128 \ &panelType=scatter-plot \ &channels=x:velocity,y:pressure,color:temperature ``` #### Geo Map with Channel roles Assigns latitude, longitude, and color Channels using role prefixes. Without role prefixes, the Geo Map Panel detects latitude and longitude Channels by name. For the full list of supported role prefixes, see [Geo Map Channel roles](/documentation/reference/explore-settings#geo-map-channel-roles). ``` https://app.siftstack.com/explore \ ?method=single \ &runId=8bfc7a2a-de0c-402c-bec1-089f4a69f128 \ &panelType=geo-map \ &channels=lat:location.latitude,lon:location.longitude,color:velocity ``` ### Time range #### Zoomed-in analysis Focuses on a specific time window using `startTime` and `endTime`. ``` https://app.siftstack.com/explore \ ?method=single \ &runId=8bfc7a2a-de0c-402c-bec1-089f4a69f128 \ &panelType=timeseries \ &channels=L1:df2cba99-abc2-4b36-bd16-e615b7682ace \ &startTime=2024-05-26T13:59:28.569Z \ &endTime=2024-05-26T14:02:52.232Z ``` ## Reference * [Share](/documentation/reference/explore-settings#share) * [Dynamic URLs](/documentation/reference/explore-settings#dynamic-urls) # Stream data to Sift from FlexLogger Source: https://docs.siftstack.com/documentation/integrate/stream-data-to-sift-from-flexlogger Install the Sift FlexLogger plugins to send Channel data to Sift. After completing this workflow, FlexLogger telemetry is available in Sift for analysis, either streamed live during a test or uploaded automatically once a test completes. ## Before you begin * FlexLogger 2024 Q4 or above * API access [set up](/documentation/manage/set-up-api-access) with an API key and the REST and gRPC base URLs for your Sift environment * Optional: [Set environment variables](#set-environment-variables) on the machine running FlexLogger to pre-fill plugin configuration fields ## Set environment variables Setting these Windows environment variables before adding either plugin to a FlexLogger project automatically populates the corresponding plugin settings, so you do not need to enter them manually in each plugin's configuration dialog. ## How the FlexLogger plugins work Installing the Sift FlexLogger plugin package adds two ways to send data to Sift: * Stream Channel data to Sift live, as a test runs (Sift Stream) * Upload a TDMS file to Sift once a run stops (Sift TDMS Uploader) ## Install the Sift FlexLogger plugins 1. Go to the [sift-labview Releases page](https://github.com/sift-stack/sift-labview/releases) and find the most recent release tagged `flexlogger-plugins`. Download `flexlogger_dist.zip` from that release. 2. Unzip the file. 3. Run `install_flexlogger_plugins.bat`. ## Stream live data to Sift 1. In **FlexLogger**, configure the Channels you want to stream. 2. Select **Add channels > Plug-in > Sift Stream**. 3. Click the configure (gear) icon on the Sift Stream plugin. 4. If you [set the environment variables](#set-environment-variables) beforehand, the fields are pre-filled. Otherwise, fill out the plugin settings. ## Upload a test file to Sift 1. In **FlexLogger**, configure the Channels you want to log. 2. Select **Add channels > Plug-in > Sift TDMS Uploader**. 3. Click the configure (gear) icon on the Sift TDMS Uploader plugin. 4. If you [set the environment variables](#set-environment-variables) beforehand, the fields are pre-filled. Otherwise, fill out the plugin settings. 5. Start and stop a run in FlexLogger. Stopping the run generates a TDMS file for that session, which the plugin uploads to Sift automatically as a Run, as long as the plugin is configured in that project. **Run name**: To change the Run name, edit the TDMS file name in FlexLogger's Logging Specification tab. ## Verify To verify data was received, open Sift and navigate to the Asset you configured. A new Run should appear containing the streamed or uploaded data. If no data appears, check the plugin log files at `C:\Users\Public\Documents\National Instruments\FlexLogger\Plugins\IOPlugins\Sift Stream` for error details, and confirm that the API key, gRPC URL, and REST URL were entered correctly in the plugin settings. # Visualize Sift telemetry in Grafana Source: https://docs.siftstack.com/documentation/integrate/visualize-sift-telemetry-in-grafana Connect Sift as a Grafana data source to build persistent, team-facing dashboards for live monitoring and historical analysis. After completing this workflow, you can connect Sift as a Grafana data source and build persistent, team-facing dashboards that poll Sift for telemetry data on a configurable interval, suitable for both live monitoring and historical analysis. ## Before you begin * A compatible version of Grafana * See [Sift Grafana plugin](https://grafana.com/grafana/plugins/sift-grafana-datasource/) for compatibility requirements * An Asset with ingested telemetry data * A [Sift API key](/documentation/manage/set-up-api-access) * Your [Sift REST API base URL](/documentation/manage/set-up-api-access) ## How the Grafana plugin works The Sift Grafana plugin adds Sift as a data source inside Grafana. Once configured, Grafana polls the Sift backend on a configurable interval, displaying data as soon as Sift has ingested it. Panels can query raw Channel data or apply a Calculated Channel expression before plotting. Sift is a standard Grafana data source and can be combined with any other Grafana-compatible source in the same dashboard. ## Install and configure the Sift plugin 1. In **Grafana**, install the **Sift** data source plugin. 2. Add **Sift** as a new data source. 3. Enter your Sift REST API base URL and API key. 4. Save the data source configuration and verify the connection. ## Build a dashboard panel 1. In **Grafana**, create a new dashboard and add a new panel. 2. Select **Sift** as the data source. 3. Select a query type: * **Channels** to plot raw telemetry from a specific Channel. * **Calculated Channels** to apply a Sift expression to one or more Channels before plotting. 4. Run the query to preview the data. 5. Save the panel and the dashboard. ## Verify To verify the connection is working, confirm the panel displays a time-series plot with one trace per Channel query. If the panel shows no data, confirm the following: * The Grafana time range overlaps with the Run's data window in Sift. Adjust the time range to match the timestamps of your Run. * The data source configuration was saved successfully. If not, check that the REST base URL and API key were entered correctly. * The selected Asset, Run, and Channel exist in your Sift workspace and contain ingested data. ## Visualizing enum and boolean channels If you are using Grafana to visualize enum or boolean state data from Sift, the [Enum Panel](/documentation/reference/explore-settings#panel-types) in Explore provides the same capability natively. It renders discrete-state channels as a color-coded timeline without requiring a separate Grafana setup. ## Reference * [Sift Grafana plugin](https://grafana.com/grafana/plugins/sift-grafana-datasource/) * [Sift Grafana datasource](https://github.com/sift-stack/sift-grafana-datasource) # Connect an Identity Provider (IdP) Source: https://docs.siftstack.com/documentation/manage/connect-an-identity-provider Configure an external Identity Provider to manage users and groups in Sift using SCIM push provisioning. After completing this workflow, you can connect an external Identity Provider (IdP) to Sift and manage users and groups centrally, with changes in the IdP automatically synchronized to Sift. ## Before you begin * You have contacted your Sift account representative to complete the initial IdP configuration * Your IdP supports [push-based provisioning](/documentation/reference/manage/idp-settings#supported-identity-providers) ## How IdP integration works Sift connects to your IdP using SCIM (System for Cross-domain Identity Management), a standard protocol for automating user and group provisioning. To connect your IdP, you need two credentials from Sift: * An **access token**: used to authenticate those requests * A **SCIM endpoint URL**: the address your IdP sends provisioning requests to Once connected, Sift synchronizes with your IdP automatically every 24 hours. Administrators can also trigger a manual sync at any time. Groups synchronized from an IdP are called external groups in Sift. Their membership and attributes remain controlled by the IdP, though permissions can be managed in Sift. ## Connect your Identity Provider (IdP) 1. Click your profile icon. 2. Select **Manage**. 3. Click **Manage Identity Provider**. 4. Click **Generate Token** to generate an access token for IdP verification. 5. In the **SCIM Server URL** section, click **Copy** to copy the SCIM endpoint URL. 6. Use the token and SCIM URL to configure your IdP. ## Optional: Synchronize your organization manually Trigger a manual sync to apply changes from your IdP to Sift without waiting for the next automatic sync. **Synchronizing**: When synchronizing Sift with your organization, the system will update your account to match the IdP's data, which may create new users or deactivate existing ones, create or delete external groups, and add or remove users from those external groups. All changes are determined by your IdP's current configuration. 1. Click your profile icon. 2. Select **Manage**. 3. Click **Manage Identity Provider**. 4. Click **Sync Organization**. ## Optional: View token history View the history of generated tokens used for IdP verification. 1. Click your profile icon. 2. Select **Manage**. 3. Click **Manage Identity Provider**. 4. Click **Open**. ## Next steps * [Integrate an Identity Provider with Sift](/tutorials/manage/tutorial-1): Learn how to integrate an external IdP with Sift using Microsoft Entra ID as an example, with steps that apply to any IdP that supports push provisioning. ## Reference * [Identity Provider settings](/documentation/reference/manage/idp-settings) # Get alerted when a limit is breached Source: https://docs.siftstack.com/documentation/manage/get-alerted-when-a-limit-is-breached Set up a webhook to receive notifications in an external system when a Rule is violated or resolved during live data ingestion. After completing this workflow, you can configure a webhook on a Rule so Sift automatically sends a notification to any system that accepts HTTP requests (such as Slack, PagerDuty, or Jira) the moment a limit is breached or resolved. ## Before you begin * You have an **Admin** or **Editor** role. * You are familiar with how [Sift organizes data into Assets, Channels, and Runs](/documentation/get-started/data-model). * You have at least one Rule configured for the Asset you want to monitor. * You have a destination URL from the external system you want to notify. ## How webhook alerts work A webhook is an HTTP POST request Sift sends to an external system when a Rule is violated or resolved during live data ingestion. You do not need to be watching data in Sift. Sift detects the condition and sends the notification automatically to the system of your choice. To set up an alert, create a webhook in the Manage workspace and attach it to the Rule you want to monitor. Once the Rule is published, the webhook fires automatically. ## Create a webhook 1. Click your profile icon. 2. Select **Manage**. 3. In the **Manage** navigation menu, click **Webhooks**. 4. Click **Create webhook**. 5. In the **Webhook name** box, enter a name for the webhook. 6. In the **Trigger event type** list, select **Rule Violation**. 7. In the **Destination URL** box, enter the URL of the external system that will receive the notification. 8. Click **Next**. 9. Optional: In the **Custom HTTP headers** section, add any headers required by the destination system. 1. Click **+ Add header**. 2. In the **Key** list, select an HTTP header. 3. In the **Value** box, enter the corresponding value. 10. In the **Payload config template** list, select a template. * Select a predefined template for services like Slack, OpsGenie, Jira, or PagerDuty. * Select **No template** to define a custom payload. 11. In the **Payload body** box, customize the payload. * You can use built-in variables such as `{{.RuleName}}`, `{{.Status}}`, and `{{.AssetName}}` to include dynamic data in the notification. For a full list of available variables, see [Webhooks settings](/documentation/reference/manage/webhooks-settings#built-in-variables). 12. Optional: Click **Test webhook** to send a test request to the destination URL and confirm it is received correctly. 13. Click **Save**. ## Attach the webhook to a Rule Once the webhook is created, attach it to the Rule you want to monitor. 1. Select **Rules** in the navigation. 2. In the **Rules** table, click the Rule you want to configure the webhook for. 3. Click **Edit**. 4. In the **Webhook** section, click **Configure webhook**. 5. In the **Webhooks** table, click the name of the webhook you created. 6. Click **Select**. 7. Click **Save**. 8. Click **Publish**. ## Verify the webhook Once live data is flowing, confirm the webhook is firing as expected. 1. Click your profile icon. 2. Select **Manage**. 3. In the **Manage** navigation menu, click **Webhooks**. 4. In the **Webhooks** table, click the webhook you want to verify. 5. Click the **Logs** tab. 6. Review the log entries to confirm the webhook fired and the destination system received the notification. * If a webhook failed to fire, the log entry includes the reason for the failure. ## Reference * [Webhooks settings](/documentation/reference/manage/webhooks-settings) # Recover failed ingestion data Source: https://docs.siftstack.com/documentation/manage/identify-and-recover-failed-ingestion-data Review DLQ entries, download failed data, and reingest it after resolving the issue. After completing this workflow, you can review Dead Letter Queue (DLQ) entries for data that failed to ingest, download the data along with the reasons it failed, resolve the issue, and reingest the data. ## Before you begin * You are familiar with how [Sift organizes data into Assets, Channels, and Runs](/documentation/get-started/data-model). ## How Data Processing works Data processing errors are logged in the Dead Letter Queue (DLQ) when ingestion fails due to invalid values or parameters. These errors can be reviewed by navigating to the Manage section and selecting **Data Processing** in the Sift interface. The following table describes the most common error types: The following table describes how long error data is retained in Sift: ## Review and download DLQ data 1. Click your profile icon. 2. Select **Manage**. 3. In the **Manage** navigation menu, click **Data Processing**. 4. In the **Data Processing** table, locate the error record you want to investigate. 5. Click **Export** to download the data and the reasons why it was sent to the DLQ. 6. Review the downloaded data to understand the issue. 7. Resolve the issue independently or work with Sift to resolve it, then reingest the data. ## Recover data lost during a streaming interruption A brief network interruption during streaming ingestion is not always retried indefinitely. The streaming ingestor's retry policy uses exponential backoff: if a connection cannot reconnect quickly, retry delays reach the multi-second range, and data for that window can be permanently dropped instead of automatically backfilled. To recover a gap caused by a streaming interruption, export the affected time range (for example, as a Parquet file) and reimport it. See [Import telemetry from a file](/documentation/ingest/data-import/import-data-from-a-file). ## Next steps * To monitor DLQ metrics as time-series data, see [Monitor ingestion health](/documentation/ingest/monitor-ingestion-health). # Manage user access Source: https://docs.siftstack.com/documentation/manage/manage-user-access Invite users, manage their status, and organize them into groups to control access to Sift. After completing this workflow, you can control who has access to Sift and what they can do by inviting users, organizing them into groups, and assigning roles that define their permissions. ## Before you begin * You have an **Admin** role. Only Admins can invite, deactivate, and reactivate users. ## How user management works Access in Sift is controlled through groups. Each user belongs to one or more groups, and each group is assigned a role that determines what its members can do. Users with email addresses matching any of the organization's configured domains are added automatically during sign-up. Users outside all configured domains must be manually invited and assigned to a group. **Email domain**: Organizations can be configured to allow more than one email domain (for example, when a company is acquired and employees use a new email address). To add an additional allowed domain to your organization, contact Sift support. Only users with the **Admin** role can invite, deactivate, and reactivate user accounts. Deactivating a user account automatically deactivates all API keys associated with that user. To manage permissions for users, Sift uses authorization models. By default, [Role-Based Access Control (RBAC)](/documentation/reference/manage/authorization-models-settings#role-based-access-control-rbac) controls access through the groups you create in Sift. For more granular control, [Attribute-Based Access Control (ABAC)](/documentation/reference/manage/authorization-models-settings#attribute-based-access-control-abac) can be configured to further restrict access within the boundaries set by RBAC. To set up ABAC, see [Set up attribute-based access policies](/documentation/manage/set-up-data-access-governance). ## Invite a user 1. Click your profile icon. 2. Select **Manage**. 3. Click **Users**. 4. Click **Invite User**. 5. In the **Email** box, enter the user's email address. 6. In the **Group** list, assign the user to a group. 7. Click **Send Invite**. ## Deactivate a user 1. Click your profile icon. 2. Select **Manage**. 3. In the **Users** table, find the row corresponding to the user you want to deactivate. 4. In that row, click **Menu**. 5. Select **Deactivate**. ## Reactivate a user 1. Click your profile icon. 2. Select **Manage**. 3. Click **Show Inactive**. 4. In the **Users** table, find the row corresponding to the user you want to reactivate. 5. In that row, click **Menu**. 6. Select **Activate**. ## Create a group 1. Click your profile icon. 2. Select **Manage**. 3. Click the **Groups** tab. 4. Click **Create Group**. 5. In the **Group name** box, enter a name for the group. 6. In the **Role** list, select a [role](/documentation/reference/manage/user-management-settings#group-roles) for the group. 7. Optional: Click the **All Assets** toggle to the off position to restrict the group's access to a defined subset of [Assets](/documentation/reference/manage/user-management-settings#groups). 8. Click **Create**. ## Reference * [User Management settings](/documentation/reference/manage/user-management-settings) # Organize resources with Metadata Source: https://docs.siftstack.com/documentation/manage/organize-and-filter-resources-with-metadata Define a structured taxonomy using Metadata keys to organize, categorize, and filter resources including Runs, Campaigns, and Annotations across your workspace. After completing this workflow, you can define structured Metadata key-value pairs once at the organization level, apply them across Runs, Assets, Rules, and other resources, and use them to filter and search with a consistent taxonomy across your team. ## Before you begin * You have an **Admin** or **Editor** role. * You are familiar with how [Sift organizes data into Assets, Channels, and Runs](/documentation/get-started/data-model). ## How Metadata works A Metadata key is a structured label defined once at the organization level and applied to any supported [resource](/documentation/reference/manage/metadata-settings#resources-that-support-metadata) in Sift, such as a Run, Asset, Rule, or Calculated Channel. Each key has a fixed [data type](/documentation/reference/manage/metadata-settings#data-types) (String, Number, or Boolean) that cannot be changed after creation, ensuring values remain consistent across the workspace. For example, you could define a key called `test_phase` of type String and apply it to Runs with values like `EVT` (Engineering Validation Test), `DVT` (Design Validation Test), or `PVT` (Production Validation Test). Any engineer on your team can then filter Runs by `test_phase` to find exactly the data they need. ## Create a Metadata key Metadata keys are created in the Manage workspace and are available across the entire organization once created. 1. Click your profile icon. 2. Select **Manage**. 3. In the **Manage** navigation menu, click **Metadata**. 4. Click **Create Metadata Key**. 5. In the **Name** box, enter a name for the Metadata key. 6. In the **Type** list, select a data type for the Metadata key. 7. Click **Create**. ## Add values to a Metadata key For String and Number keys, you can predefine a set of values that will appear as selectable options when the key is applied to a resource. This option is not available for Boolean keys, since their values are limited to `true` and `false`. 1. Click your profile icon. 2. Select **Manage**. 3. In the **Manage** navigation menu, click **Metadata**. 4. In the **Metadata** table, locate the Metadata key you want to add values to. 5. Click **Options**. 6. Select **View values**. 7. In the **Enter \[data type] value** box, enter a value. 8. Click **Add value**. ## Apply Metadata to a resource Once a Metadata key exists, you can apply it to any supported resource. The steps vary slightly depending on the resource type. ### Runs 1. Select **Runs** in the navigation. 2. Click the Run you want to add Metadata to. 3. Click **Edit**. 4. Click **Add Metadata**. 5. In the **Select or create key** list, select a Metadata key. 6. In the **Enter or select value** list, select a value. 7. Click **Save changes**. ### Assets 1. Select **Assets** in the navigation. 2. Click the Asset you want to add Metadata to. 3. Click **Edit Metadata**. 4. Click **+ Add Metadata**. 5. In the **Select or create key** list, select a Metadata key. 6. In the **Enter or select value** list, select a value. 7. Click **Save changes**. ### Rules and User-Defined Functions Rules and User-Defined Functions follow the same pattern and both require publishing after saving. 1. Select **Rules** or **User-Defined Functions** in the navigation. 2. Click the resource you want to add Metadata to. 3. Click **Edit**. 4. Click **Add Metadata**. 5. In the **Select or create key** list, select a Metadata key. 6. In the **Enter or select value** list, select a value. 7. Click **Save**. 8. Click **Publish**. ### Reports 1. Select **Reports** in the navigation. 2. Click the Report you want to add Metadata to. 3. Click **Edit Metadata**. 4. Click **Add Metadata**. 5. In the **Select or create key** list, select a Metadata key. 6. In the **Enter or select value** list, select a value. 7. Click **Save**. ### Report Templates 1. Select **Report Templates** in the navigation. 2. Click the Report Template you want to add Metadata to. 3. Click **Edit**. 4. Click **Add Metadata**. 5. In the **Select or create key** list, select a Metadata key. 6. In the **Enter or select value** list, select a value. 7. Click **Save changes**. 8. Click **Save**. ### Campaigns 1. Select **Campaigns** in the navigation. 2. Click the Campaign you want to add Metadata to. 3. Click **Add Metadata**. 4. In the **Select or create key** list, select a Metadata key. 5. In the **Enter or select value** list, select a value. 6. Click **Save**. ### Calculated Channels 1. Select **Calculated Channels** in the navigation. 2. Click the Calculated Channel you want to add Metadata to. 3. Click **Edit**. 4. Click **Add Metadata**. 5. In the **Select or create key** list, select a Metadata key. 6. In the **Enter or select value** list, select a value. 7. Click **Save**. 8. Click **Save changes**. ## Filter resources by Metadata Once Metadata is applied to resources, use it to filter and find specific resources across your workspace. 1. Select the resource type you want to filter in the navigation (for example, **Runs** or **Assets**). 2. Click **Metadata**. 3. In the **Select key** list, select a Metadata key. 4. In the **Enter or select value** box, enter or select a value. 5. Optional: Click **+ Add** to add additional Metadata filters. ## Reference * [Metadata settings](/documentation/reference/manage/metadata-settings) # Set up API access Source: https://docs.siftstack.com/documentation/manage/set-up-api-access Create an API key and obtain the base URL needed to authenticate and send requests to the Sift API. After completing this workflow, you can create an API key and obtain the base URL required to authenticate REST or gRPC requests to the Sift API. ## How API keys work API keys in Sift are user-associated credentials used to authenticate requests to the Sift API. Each key inherits the permissions of the user it is associated with and remains valid indefinitely unless explicitly deleted. All API keys are listed under the API Keys interface, where they can also be removed. When interacting with the Sift API: * For **REST** requests using the Bearer authentication scheme, the API key must be included in the HTTP request `authorization` header. * For **gRPC** requests, the API key must be passed as a metadata field, also using the `authorization` header with the Bearer scheme. API keys can be created and managed either through the Sift UI or programmatically via the Sift API. ## Create an API key 1. Click your profile icon. 2. Select **Manage**. 3. In the **Manage** navigation menu, click **API Keys**. 4. Click **Create API Key**. 5. In the **Name** box, enter a name for the API key. 6. In the **User** list, select the user email to link to the API key. 7. Click **Create**. **Key value**: Upon creation, the key value is displayed once and cannot be retrieved later. Store it securely using a secret management tool of your choice. ## Obtain the base URL The REST or gRPC base URL can be obtained through the Sift UI. The base URL tells your application exactly where to send API requests and ensures that your requests reach the correct environment. 1. Click your profile icon. 2. Select **Manage**. 3. In the **Manage** navigation menu, click **API Keys**. ## Use API keys across multiple environments If you connect to more than one environment, each environment requires its own API key. Create a separate key for each environment, and use the matching key when you authenticate a request against that environment. ## API rate limits Sift enforces rate limits on its API to keep the platform fast and reliable for everyone. ### How limits are applied * Per organization * Per API endpoint * Set well above typical usage (you won't be seeing this most of the time) ### What happens if you exceed a limit * **HTTP API:** status `429 Too Many Requests`, with a message indicating waiting before retrying. * **gRPC API:** status `RESOURCE_EXHAUSTED`, with a message indicating waiting before retrying. These responses are safe to retry because the request was not processed. Retrying after the indicated delay has no unintended side effects. ### Limit values Sift does not publish specific per-endpoint limits, and they can change over time as the platform develops. If you have a planned operation that legitimately needs higher throughput on a given endpoint, contact Sift support in advance and Sift can temporarily raise your limit for the set duration. ### Tips to avoid rate limiting * Batch where the API supports it rather than looping single-record calls. * Avoid tight retry loops without backoff. * Spread large backfills or migrations over time instead of issuing them all at once. # Set up attribute-based access policies Source: https://docs.siftstack.com/documentation/manage/set-up-data-access-governance Use Attribute-Based Access Control (ABAC) to control access to Sift resources. After completing this workflow, you can define fine-grained access control policies using Sift's Attribute-Based Access Control (ABAC) approach, based on attributes assigned to users and resources. ## Before you begin * You have an **Admin** role. * You are familiar with how [Sift organizes data into Assets, Channels, and Runs](/documentation/get-started/data-model). ## How ABAC setup works ABAC controls access to Sift resources by evaluating attributes on users, user groups, and resources against policies you define. You can protect **Assets**, **Channels**, and **Runs** with ABAC. Setup follows a deliberate sequence: label users (or user groups) and resources with attributes, then define a policy that connects them. No access changes occur until a policy is active. You can label users individually or label a user group. Group attributes work well when an attribute applies to the whole team, membership turns over frequently, or your identity provider only exposes attributes at the group level. Polices can reference a user's individual attributes and the group attributes for groups that a user is a member of. Assigning attributes to groups instead of individuals avoids having to maintain sets of attributes across individual users. For example, suppose your organization runs a sensitive satellite program called `Artemis`, and only engineers with the correct clearance should access its telemetry data in Sift. Here's how ABAC handles it: 1. Create a user attribute `clearance` (type: Enum Set) and assign \[`Artemis`, `Apollo`] to the cleared engineers. This labels the user. No access changes yet. 2. Create a resource attribute `program_classification` (type: Enum) and assign Artemis to the relevant Assets and Channels. This labels the resource. No access changes yet. 3. Create a policy that grants access only when a user's `clearance` contains the resource's `program_classification`. Access changes immediately once the policy is active. Now only engineers whose `clearance` includes `Artemis` can access the Artemis resources. Others see nothing, even if their RBAC role would otherwise allow it. ## Step 1: Create and assign a user attribute ### Create a user attribute 1. Click your profile icon. 2. Select **Manage**. 3. In **Access Control**, click **User attributes**. 4. Click **Create User Attribute**. 5. In the **Type** list, select a [data type](/documentation/reference/manage/authorization-models-settings#attribute-data-types). 6. In the **Name** box, enter a name for the attribute. Use a name tied to real concepts in your organization so that someone reading a policy can immediately understand what the attribute means. 7. Optional: In the **Description** box, enter a description to clarify how the attribute is intended to be used in policies. 8. Click **Save**. ### Assign a user attribute Assigning this attribute does not change access. It only labels the user so that a policy can later reference this attribute. 1. In **Access Control**, click **User Attributes**. 2. In the **User attributes** table, locate the attribute to use. 3. Click **Options**, and then select **Assign**. 4. In **Assign User Attributes**, in **Groups** or **Users**, select a group or user, and click **Update**. * You can select any user or group, but do not select yourself. You can change this selection later. * Once the policy is active, this user or group's RBAC permissions will be further controlled for this specific Asset. 5. Set the attribute value for the selected user or group. 6. Click **Next** to review your changes. 7. Review the assignment summary, then click **Update** to confirm. **No access**: At this point, no access has changed. The user still has the same RBAC role and permissions as before. Access will only change after you create a policy that references this attribute. ## Step 2: Create and assign a resource attribute ### Create a resource attribute 1. In **Access Control**, click **Resource Attributes**. 2. Click **Create Resource Attribute**. 3. Configure the attribute [settings](/documentation/reference/manage/authorization-models-settings#attribute-data-types) and click **Save**. ### Assign a resource attribute Assigning this attribute does not change access. It only labels the resource so that a policy can later reference this attribute. 1. In **Access Control**, click **Resource Attributes**. 2. In **Resource Attributes**, find the resource attribute to use. 3. Click **Options**, then select **Assign**. 4. Select the resource type you want to manage: **Assets**, **Channels**, or **Runs**. 5. In the search field, enter the name of the resource to manage. 6. In the search results, select your resource. 7. Click **Update**. 8. Select a value for the attribute. 9. Click **Next**. 10. Review your changes, and then click **Update**. ## Step 3: Create a policy 1. In **Access Control**, click **Policies**. 2. Click **Create Policy**. 3. Configure the [policy settings](/documentation/reference/manage/authorization-models-settings#policy-settings) and click **Create**. **Implementation**: Creating the policy immediately grants or denies access. ## Next steps * [Getting started with attribute-based access control (ABAC)](/tutorials/manage/tutorial-3): A hands-on tutorial that walks through using ABAC to protect a specific Asset by creating user and resource attributes and an explicit deny policy. By the end, you will have restricted a user's access to a sensitive Asset without changing their RBAC role. ## Reference * [Authorization models settings](/documentation/reference/manage/authorization-models-settings) # Annotations reference Source: https://docs.siftstack.com/documentation/reference/annotations-reference Status definitions and file attachment limits for Data Review Annotations, and creation, Rule, and Family behavior for Phase Annotations This page covers the status workflow and file attachment behavior for Data Review Annotations, and the creation, Rule, and Family behavior of Phase Annotations, described in [Phase Annotations](#phase-annotations) below. See [Annotation fields](/documentation/reference/explore-settings#annotation-fields) for the fields available when creating either type. ## Statuses The following statuses apply to Data Review Annotations only. Phase Annotations have no status. ## Transitioning between states Use the status control in the Annotation details panel to transition an Annotation between **Open**, **Failed**, and **Accepted**. All state transitions are recorded in the Annotation's activity log with a timestamp and the user who made the change. ## How Annotation states appear in Reports When a Rule is evaluated in a Report, the status displayed for that Rule is derived from the states of its Annotations: * If all Annotations are **Open**: the Rule shows as Open. * If at least one Annotation is **Failed**: the Rule shows as Failed, regardless of other Annotation states. * If all Annotations are **Accepted**: the Rule shows as Accepted. * If the Rule generated no Annotations: the Rule shows as **Passed**. Passed Rules are not shown in the Report by default; filter for Passed Rules to see them. Changing an Annotation's state immediately updates the Rule's displayed status in the Report. A Rule that generated a Phase Annotation is hidden from the Report's Rules panel by default, since Phase Annotations carry no Open, Failed, or Accepted state. Select **All** in the Rules panel filter to view the Rule and its Phase Annotation. ## File attachments Files can be attached to Annotations and to individual comments on Annotations. ### Supported file types ### Size limits ## Phase Annotations A Phase Annotation marks a period or stage in a Run, such as "Engine Ignition" or "Max-Q." Unlike a Data Review Annotation, a Phase Annotation has no status, cannot be assigned to a user, and does not support file attachments. ### Create a Phase Annotation Create a Phase Annotation manually in Explore using the **Annotations** tab or the **Select X** tool. See [Investigate a telemetry anomaly](/documentation/analyze/investigate-telemetry-anomaly#investigate-an-anomaly) for the steps, and [Annotation fields](/documentation/reference/explore-settings#annotation-fields) for the available fields. A Rule can also generate a Phase Annotation instead of a Data Review Annotation when its condition evaluates to true, marking a period rather than flagging an issue for triage. In the Rule editor's **Annotation Details** section, select **Phase** instead of **Data Review** to configure this. ### Use in Families An Annotation alignment on a Family resolves T-0 to the timestamp of a matching Annotation on each Run. Phase Annotations are the type used for this purpose, since they mark a named event without requiring the review status fields a Data Review Annotation carries. See [Configure alignments](/documentation/analyze/families/group-runs-into-a-family#step-4-configure-alignments). ### API behavior Phase Annotations are created, retrieved, and updated through the same [Annotation API](/api/reference/protocol-buffers/annotations) as Data Review Annotations, distinguished by the `annotation_type` field. A Phase Annotation's `state` field must be left unset; setting it returns an error. ## Behavior ## Link to an Annotation To open a specific Annotation directly, use its ID in the URL: `https://app.siftstack.com/annotation/`. ## Related workflows * [Detect and review issues in a Run](/documentation/review/detect-and-review-issues-in-a-run) * [Triage and close out flagged issues](/documentation/review/triage-and-close-out-flagged-issues) * [Group Runs into a Family](/documentation/analyze/families/group-runs-into-a-family) # Assets reference Source: https://docs.siftstack.com/documentation/reference/asset-settings Settings, options, and behaviors for Assets in Sift. Assets in Sift represent physical or virtual entities that generate time-series data through their Channels. They can represent a wide range of systems, from tangible objects such as vehicles and hardware testbeds to intangible systems like simulators or continuous integration (CI) pipelines. Assets are the sources of telemetry data, meaning any entities that produce structured measurements over time. ## Asset modeling Asset modeling in Sift is about deciding which physical or virtual systems should be represented as Assets and how to structure them to reflect your test setup, telemetry flow, or workflow. Good modeling helps ensure that telemetry is organized clearly, supports analysis features like Rules and Runs, and enables long-term reuse and discoverability. The following table summarizes the two most common Asset modeling strategies in Sift. ## Naming conventions When naming an Asset, aim to make the name clear enough that anyone can understand three key things just by looking at it: its **type**, a unique **identifier**, and a **modifier** that describes its environment or context. A common and recommended convention is to separate these parts with underscores for readability. ``` type_identifier_modifier ``` Additional naming guidelines: * Do not include special characters in Asset names. * Use hyphens to separate words or fill spaces within token names. * Use lowercase letters in Asset names. This is not required, since Asset names are case insensitive, but it improves consistency and readability. The stored display name retains the casing from the first ingest. ## Create an asset Creating an Asset requires the **Create asset** [permission](/documentation/reference/manage/authorization-models-settings#role-permissions). Assets can be created in the following ways: * **Automatically during ingestion.** Uploading a file, creating a Run, or setting up an ingestion config creates the named Asset if it does not already exist. * **Explicitly, before any data exists.** Select **New Asset** on the Assets page, or call `CreateAsset` on the [Asset API](/api/reference/protocol-buffers/assets). Creating Assets in advance lets you apply your [naming conventions](#naming-conventions) during planning instead of deciding names at the moment data lands. Selecting **New Asset** opens a modal where you enter the Asset name and optionally add tags and metadata. Sift validates the name and returns an error if an Asset with that name already exists. On success, Sift opens the new Asset's overview page. An Asset created this way is empty until data arrives. Streamed data and file uploads that reference the Asset name attach to the existing Asset rather than creating a duplicate. ## Rule evaluation scope Rules in Sift are evaluated within the scope of a single Asset and its Channels. Any telemetry you want to analyze together using Rules must be grouped under the same Asset. It is acceptable for multiple clients or data sources to stream to the same Asset simultaneously, as long as they represent parts of the same system or workflow. ## Ingestion monitoring **sift\_app** is a built-in system Asset that provides real-time telemetry about your data pipeline's performance and stability. It surfaces internal metrics through the same infrastructure you use for your own data, allowing you to build dashboards and set up alerts for specific Channels using familiar tools. The **sift\_app** Asset is organized into four subsections. Each subsection represents a different layer of the ingestion journey, moving from your local client to Sift's internal processing, error handling, and file-based data imports. ```bash theme={null} sift_app ├── data_import ├── dlq_ingestion ├── ingest_grpc └── stream ``` ### data\_import The **data\_import** subsection provides telemetry for data imported into Sift via file upload, such as CSV, Parquet, Ch10, or TDMS files. Metrics are emitted when a data import Job completes (successfully or with an error). ```bash theme={null} sift_app ├── data_import └── └── processor └── [Various Channels] ``` **Applicability**: These metrics apply only to data imported via file upload (for example, through the UI, upload APIs, or Jobs that process uploaded files), and not to data ingested through the gRPC stream APIs. **Monitor data imports**: Use `error_flag` and `import_duration_seconds` to track failures and Job duration, and `file_size_bytes` to monitor import volume. ### dlq\_ingestion The **dlq\_ingestion** subsection is dedicated to the Dead Letter Queue (DLQ) and is your primary resource for troubleshooting records that failed to ingest. ```bash theme={null} sift_app ├── dlq_ingestion └── ├── └── count └── observed_run_ids ``` ### ingest\_grpc The **ingest\_grpc** subsection monitors the internal Sift components responsible for managing and observing your data streams. ```bash theme={null} sift_app ├── ingest_grpc └── └── stream_monitor └── [Various Channels] ``` **Applicability**: These metrics apply only to data ingested through the gRPC stream APIs (`IngestWithConfigDataStream` and `IngestArbitraryProtobufDataStream`), and not to data uploaded via the UI or upload APIs. **Monitor data**: Use `total_message_size_bytes` to build ingestion volume dashboards, and `messages_with_high_time_drift_count` to monitor for ingestion anomalies. ### stream The **stream** subsection provides visibility into the behavior of the Rust `sift-stream` client implementation. ```bash theme={null} sift_app ├── stream └── └── └── [Various Channels] ``` **Getting these metrics**: These metrics are emitted by the stream client. To receive them, ensure you are using the latest versions of either the Rust crate `sift_stream` or the Python library `sift_client`. ## Behavior The following table describes known constraints and behaviors to be aware of when working with Assets. **Combining sources into one Run**: To add a second data source to a Run already in progress (for example, for a different port or connection), select **Existing** under Run and pick that Run. You do not need to create a new Run. Because Channel names are shared across an entire Asset, prefix each source's Channel names to avoid naming collisions between sources. # Calculated Channels reference Source: https://docs.siftstack.com/documentation/reference/calculated-channel-settings Settings, options, and behaviors for Calculated Channels in Sift. Calculated Channels are derived signals computed from one or more existing Channels using a CEL expression. They allow engineers to define custom metrics, transform raw telemetry, and derive new signals without modifying the original data. Once created, a Calculated Channel is available in Explore for visualization and as an input for Rules and other Calculated Channels. Sift supports two types of transformations: * **Stateless**: Processes each data point independently. Ideal for unit conversions and threshold checks. * **Stateful**: Retains context over time using rolling windows. Useful for moving averages, rates of change, and trend detection. ## Settings The following table describes each setting available when creating or editing a Calculated Channel. ## Behavior The following table describes known constraints and behaviors to be aware of when working with Calculated Channels. # Campaigns reference Source: https://docs.siftstack.com/documentation/reference/campaigns-reference Data model, operations, filters, and permissions for Campaigns in Sift A Campaign groups Reports from multiple Runs into a single workspace for coordinated review. This page covers the Campaign data model, supported operations, list filters, and access control behavior. ## Data model ### Campaign fields ### CampaignReport fields Each Report in a Campaign exposes a summary of its rule evaluation results. ## List Campaigns filters Use a [CEL expression](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions) with the `filter` parameter when listing Campaigns. Campaigns can be ordered by `name`, `created_date`, or `modified_date`. The default order is `created_date` descending (newest first). ## List Campaign Annotations filters Use a CEL expression with the `filter` parameter when listing Annotations within a Campaign. Annotations can be ordered by `created_date`, `modified_date`, `start_time`, or `end_time`. The default order is `created_date` ascending (oldest first). ## Permissions ## Metadata Campaigns support user-defined metadata. Metadata is searchable and can be used to filter Campaigns in lists. See [Organize resources with Metadata](/documentation/manage/organize-and-filter-resources-with-metadata) for steps on adding metadata to a Campaign. ## Related workflows * [Campaigns: track a multi-Run review effort](/documentation/review/track-a-multi-run-review-campaign) * [Detect and review issues in a Run](/documentation/review/detect-and-review-issues-in-a-run) * [Triage and close out flagged issues](/documentation/review/triage-and-close-out-flagged-issues) # Channels reference Source: https://docs.siftstack.com/documentation/reference/channels-reference Naming rules and supported data types for Channels in Sift Channels in Sift represent individual time-series signals, typically originating from sensors or telemetry sources on an Asset. Each Channel is associated with a specific data type. ## Naming restrictions * A Channel name must not exceed **255 characters**. Calculated Channel names are limited to **253 characters**. * Channel names must contain only 7-bit ASCII characters. Extended or non-ASCII characters are not allowed. * The following characters are not permitted in Channel names: `" ␞ ␟ ␝ ␜ \ ` \~ |\` ## Behavior The following table describes known constraints and behaviors to be aware of when working with Channels. ## Related workflows * [Import data from a file](/documentation/ingest/data-import/import-data-from-a-file) * [Detect deviations automatically using Rules](/documentation/review/detect-deviations-automatically-using-rules) # Sift CLI reference Source: https://docs.siftstack.com/documentation/reference/cli-reference Complete command, subcommand, and flag reference for the Sift CLI. This page documents every command, subcommand, and flag in the Sift CLI. For installation and configuration, see [Sift CLI](/documentation/cli/sift-cli). ## Sift CLI how-tos * [Sift CLI setup](/documentation/cli/sift-cli) * [Import files with the Sift CLI](/documentation/cli/import-files-with-the-sift-cli) * [Export data with the Sift CLI](/documentation/cli/export-data-with-the-sift-cli) ## Global flags These flags apply to any command. | Flag | Description | | ------------------ | -------------------------------------------- | | `--profile ` | The profile to use. Defaults to `default`. | | `--disable-tls` | Disable TLS for non-cloud Sift environments. | | `--version` | Print the CLI version. | | `--help` | Print help for a command or subcommand. | ## config Manage Sift CLI configuration. The config file is named `sift.toml` and lives in your user data directory. | Subcommand | Description | | --------------- | ------------------------------------------------------ | | `config show` | Display the contents of the current config file. | | `config where` | Show the path to the current config file. | | `config create` | Create a new config file. Fails if one already exists. | | `config update` | Update fields in the existing config file. | ### config update | Flag | Description | | ------------------------- | -------------------------------------------------------------- | | `--interactive` / `-i` | Edit or create a profile through prompts. Ignores other flags. | | `--grpc-uri` / `-g ` | Base gRPC endpoint for Sift. | | `--rest-uri` / `-r ` | Base REST endpoint for Sift. | | `--api-key` / `-k ` | API key used for authentication. | The command writes to the profile named by the global `--profile` flag, or `default` when omitted. ## ping Ping the Sift API to verify credentials and connectivity. Takes no flags. ```bash theme={null} sift-cli ping ``` ## import Import time series files into Sift. ### Common import flags These flags apply to the Parquet, TDMS, HDF5, and ULog import commands. | Flag | Description | | ----------------------- | -------------------------------------------------------------------- | | `` | Path to the file to import. Positional. | | `--asset` / `-a ` | Name of the Asset this data belongs to. Required. | | `--run` / `-r ` | Run name to associate with the import. | | `--run-id ` | ID of an existing Run to add data to. Takes precedence over `--run`. | | `--wait` / `-w` | Wait until the import finishes processing. | | `--preview` / `-p` | Preview the parsed schema without uploading. | ### import csv Import a CSV file. Unless specified, all columns are inferred as type string or double. When you pass `--channel-column`, supply a `--data-type`, `--unit`, and `--description` for each one; the counts must match. | Flag | Description | | -------------------------------------- | --------------------------------------------------------------------------- | | `` | Path to the CSV file. Positional. | | `--asset` / `-a ` | Name of the Asset. Required. | | `--run` / `-r ` | Run name to associate with the import. | | `--header-row ` | Row containing column headers, 1-based. Default `1`. | | `--first-data-row ` | Row where data starts, 1-based. Default `2`. | | `--channel-column` / `-c ` | 1-based index of a column to override. Repeatable. | | `--data-type` / `-d ` | Data type for each `--channel-column`. Repeatable. | | `--unit` / `-u ` | Unit for each `--channel-column`. Repeatable. | | `--description` / `-n ` | Description for each `--channel-column`. Repeatable. | | `--enum-config` / `-e ` | Enum configuration pairs ``, for example `"0,start\|1,stop"`. | | `--bit-field-config` / `-b ` | Bit-field triplets ``, for example `"12v,0,4\|led,4,4"`. | | `--time-column` / `-t ` | 1-based index of the time column. Default `1`. | | `--time-format` / `-f ` | Time format used in the file. Default `absolute-rfc3339`. | | `-s ` | Directory containing backup files. Defaults to your OS data directory. | | `--cleanup` / `-c` | Delete backup files after a successful upload. | | Subcommand | Description | | -------------------------- | --------------------------------------------------------------------- | | `import backups ls [path]` | List backup files in a directory. Defaults to your OS data directory. | ## export Export Asset or Run data from Sift. ### Common export flags | Flag | Description | | ------------------------------------ | -------------------------------------------------------------- | | `--output` / `-o ` | The file to generate. Required. | | `--format` / `-f ` | Output format: `csv`, `parquet`, or `sun` (WinPlot). Required. | | `--channel` / `-c ` | Channel name to include. Repeatable. | | `--channel-id ` | Channel ID to include. Repeatable. | | `--channel-regex` / `-x ` | Regular expression selecting Channels by name. | | `--calculated-channel ` | Calculated Channel name to include. Repeatable. | | `--calculated-channel-id ` | Calculated Channel ID to include. Repeatable. | | `--calculated-channel-regex ` | Regular expression selecting Calculated Channels by name. | | `--start
` | Address the documentation server binds to. Default `0.0.0.0:3000`. | ## Data types The `--data-type` flag accepts: `infer`, `double`, `string`, `enum`, `bit-field`, `bool`, `float`, `int32`, `uint32`, `int64`, `uint64`, `bytes`. Use `infer` to detect the type automatically while still setting values such as unit or description. ## Time formats The `--time-format` flag accepts the following values. For a relative format, set the relative start time flag to an RFC 3339 timestamp that anchors the offsets. | Type | Values | | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Absolute | `absolute-rfc3339` (default for CSV), `absolute-datetime`, `absolute-unix-seconds`, `absolute-unix-milliseconds`, `absolute-unix-microseconds`, `absolute-unix-nanoseconds` | | Relative | `relative-nanoseconds`, `relative-microseconds`, `relative-milliseconds`, `relative-seconds`, `relative-minutes`, `relative-hours` | ## Complex types modes The `--complex-types-mode` flag controls how Parquet maps, lists, and structs are imported: | Value | Description | | -------- | ---------------------------------------------------------- | | `ignore` | Ignore columns containing complex types. Default. | | `string` | Import complex types as JSON strings. | | `bytes` | Import complex types as Arrow bytes. | | `both` | Import complex types as both Arrow bytes and JSON strings. | # Explore (legacy) settings Source: https://docs.siftstack.com/documentation/reference/explore-legacy-settings Settings, options, and behaviors for Explore (legacy) features. Explore (legacy) is the previous version of Sift's telemetry visualization workspace. It remains available alongside [Explore](/documentation/reference/explore-settings). ## Table Viewer Table Viewer is a data view in the Explore (legacy) workspace. It displays telemetry values from selected Channels in a tabular format. Each column represents a Channel. Rows are aligned with the time range currently visible in the line chart and update automatically when the chart is panned or zoomed. ### Settings ### Row creation trigger options ### Filter operators Filters are applied per column and are row-based. Active filters across columns are combined using logical AND. ### Export The Table Viewer tab includes an **Export as CSV** button. Only data currently visible in the table, based on the active time range and filters, is included in the export. ## Parameterized URLs The `/explore` route accepts query parameters to preload a specific Run, Assets, Channels, and time range when Explore (legacy) opens. This allows targeted analysis views to be constructed and shared without manual setup. ### URL structure ``` https://{domainName}/explore?run={runName} \ &assets={asset1,asset2,...} \ &channels={channel1,channel2,...} \ &from={ISO8601} \ &to={ISO8601} ``` * **Format**: Line breaks and backslashes (`\`) are shown for readability. In actual use, the URL must be a single continuous string joined with `&`, without spaces or backslashes. * Parameters must be percent-encoded for proper URL handling. * If `from` and `to` are not provided, the view defaults to the start and stop times of the provided Run. ### URL parameters ### Examples **Run, Asset, and Channels** ``` https://app.siftstack.com/explore?run=run-name \ &assets=asset-name \ &channels=max_ground_temp%2Cmax_air_temp ``` **Run, Asset, Channels, and time range** ``` https://app.siftstack.com/explore?run=run-name \ &assets=asset-name \ &channels=max_ground_temp%2Cmax_air_temp \ &from=2021-09-25T10%3A14%3A11 \ &to=2021-10-14T13%3A29%3A37 ``` **Run only** ``` https://app.siftstack.com/explore?run=run-name ``` **Multiple Assets with Channels and time range** ``` https://app.siftstack.com/explore?assets=asset-one-name%2Casset-two-name \ &channels=max_air_temp%2Cmin_air_temp \ &from=2021-09-25T10%3A14%3A11 \ &to=2021-10-14T13%3A29%3A37 ``` # Explore reference Source: https://docs.siftstack.com/documentation/reference/explore-settings Settings, options, and behaviors for all Explore features. Explore is Sift's workspace for visualizing and investigating high-rate timeseries telemetry. Engineers use it to load data from Assets and Runs, arrange Panels, perform calculations, and share findings without exporting data or switching tools. ## Data sources A data source defines the telemetry context for an Explore session. It determines which Channels are available for analysis. ### Replace data source A data source can be replaced mid-session without rebuilding the Panel layout. ## Saved Explorations You can save an exploration as a snapshot of a complete Explore session. Use Saved Explorations to: * [Standardize analysis across Runs](/documentation/analyze/standardize-analysis-across-runs): save an exploration once and reuse it across different Runs so every engineer analyzes data the same way. * Build reusable templates for your team: Saved Explorations work as starting points for onboarding, pre-session setup, and operation-specific analysis. ### Save a new exploration 1. Open **Explore** and set up your workspace: add panels, plot channels, pick your runs, assets, or families, and configure compare and time range. 2. Click **Save**. 3. In **Save your exploration**, enter: * **Name** (required, up to 128 characters) * **Description** (optional) * **Visibility**: **Private** (only you can see it) or **Public** (everyone in your org can view and edit it). 4. Click **Save**. When you make changes to a Saved Exploration, a small blue dot appears on the **Save** button, reminding you to save your changes. Live mode is always turned off in the saved snapshot. Loading a Saved Exploration drops you into static-view mode regardless of how you saved it. ### Update an existing exploration When a Saved Exploration is already loaded: * **Quick overwrite**: click **Save**, in **Overwrite existing exploration?**, click **Save**. * **Rename, change description, or change visibility**: click the **Save** dropdown, then **Edit Saved Exploration**, make your changes, and click **Save**. * **Save a copy**: click the **Save as New** dropdown. The name prefills as *Copy of \{original}*, visibility resets to Private, and a new record is created. Only the original creator can change visibility on an existing Saved Exploration. Public Saved Explorations let any org member update the workspace data. ### Open a Saved Exploration From the **Save** dropdown, select **Open Saved Exploration**. Search, filter by Runs, Assets, or Families, or toggle **My Explorations** to narrow the list, then click a row. You can also open Saved Explorations for a specific Run or Asset directly from its Overview page. The **Saved Explorations** section there is pre-filtered to that Run or Asset; search within it and click a row to open it in Explore. ### What gets saved A Saved Exploration captures everything in the Explore URL: * Panels and their settings (plotted channels, axes, colors, etc.) * Dockview layout (panel positions, tabs, splits) * Selected runs, assets, and families * Compare settings and alignments * Sidebar state and time range * Draft (unpublished) calculated channels ## Share The sharing feature in Explore captures the current workspace state and generates a shareable URL. Recipients open the workspace in the exact state it was shared, with no manual reconfiguration required. ## Export data Export data is available in the Timeseries Panel toolbar. Selecting **Export data** opens a dropdown with the following options. **Export restrictions**: Nested Calculated Channels cannot be exported and are excluded from the output. Relative Time mode is not supported for export. ## User settings User settings let you define personal default display preferences for Explore across two areas: general settings that apply to all Panels, and default settings per Panel type. Defaults apply to your account only. Individual Panel settings can still be overridden at any time. User settings are stored in the browser and do not carry over to other computers. Clearing the browser cache resets all User settings to their defaults. User settings are accessed from the Explore toolbar by clicking **User Settings**. ### General settings The following settings are available under **User Settings** and apply globally across all new Panels in Explore. **Channel tree hierarchy:** The following three settings work together to control how Channel names display in the [Channel tree](#channel-tab-views): * **Channel Name Delimiter**, * **Channel Name Prefix Delimiter**, and * **Channel Leaf Keywords**. See [Channel name structure](/documentation/reference/naming-rules#channel-name-structure) for details. #### Set the display timezone 1. In the Explore toolbar, click **User Settings**. 2. Under **Default Timezone**, select the timezone you want. * **All Panels**: This applies to all new Panels for your account. Panels already open in the session are not updated. * **Single Panel**: To override the timezone on a single Panel without changing the global default, open **Panel settings**, go to the **Time-alignment** tab, and select **Timezone** from the **Alignment** list. * Timeseries, Histogram, Geo Map, FFT, and Scatter Plot Panels support a per-Panel timezone override. ### Chart type settings Default settings can be configured per Panel type. Select a Panel type from the **Chart Type Settings** dropdown to configure its defaults. Settings vary by Panel type and correspond to the individual Panel settings for each type. All Panel types are supported. #### WebGL traces Enables GPU-accelerated WebGL rendering for Timeseries Panels instead of the default ECharts renderer. Reduces slowdowns when displaying many or high-frequency Channels. ## Live mode Live mode monitors real-time telemetry as it streams into Sift. All Panel types support Live mode. Live mode is compatible with [Panel Sync](#sync-panels): when both are active, all synced Panels advance together as new data arrives. ## Panels Panels are the individual visualization units in an Explore workspace. Each Panel is independently configurable. Changing settings on one Panel does not affect other Panels. ### Panel types ### Layout Panels can be added, split, and repositioned freely within the workspace. **Add a Panel** Panels can be added at any time using the **Add** button in the workspace toolbar. **Split a Panel** Split options appear when right-clicking a Panel tab. A split duplicates the Panel in the selected direction. The new Panel is independent and can be configured separately. **Reposition a Panel** Panels can be moved to the top, bottom, left, or right of the workspace. ### Sync Panels Syncing aligns the time range across multiple Panels. Adjusting the time window in one Panel updates all synced Panels. Panel Sync is compatible with Live mode. When both are active, all synced Panels advance together as new data streams in. ### Range controls Range controls are available in the Timeseries, FFT, and Scatter Plot Panels. ### Settings Each Panel type has its own settings organized into tabs. Settings are independent per Panel. #### Timeseries **Group by options** **Sampling method options** #### Histogram #### Geo Map #### Table **Filter** Filters isolate data points that meet specific numerical criteria per Channel before rows are created. **Row creation trigger** Determines when a specific Channel contributes to generating a new row. Configured per Channel. #### FFT **Group by options** #### Scatter Plot **Scatter Plot requirements and limitations**: * Both an X-axis and a Y-axis Channel must be selected for the Scatter Plot to render data. Selecting only one Channel results in a "No data available" message. * Axis labels for the X-axis and Y-axis Channels currently appear in the legend only when **Legend Group By** is active. They are not yet rendered directly on the chart axes. * Scatter Plot and Geo Map panels can be slow when the selected time range contains many data points, because neither panel type applies multi-channel downsampling. Use a Timeseries panel with [Panel Sync](#sync-panels) enabled to narrow the time range before working with the Scatter Plot or Geo Map. **Scatter Plot and Geo Map performance**: Scatter Plot and Geo Map panels can slow down or become unresponsive when plotting large numbers of points across a wide time range. To improve performance, zoom into a narrower time range directly in the panel, or use a Timeseries panel with Panel Sync enabled to control the Scatter Plot time range via pan and zoom. #### Metrics **Aggregating integer Channels**: Mean, standard deviation, and most other aggregate calculations convert values to decimal before computing, even for an integer-typed Channel. The result is never rounded or truncated back to a whole number. #### File Viewer **Uploading media files** Video, image, and audio files are uploaded using [Explore File Viewer](/documentation/reference/explore-settings#file-viewer) and the [`CreateRemoteFile`](/api/reference/protocol-buffers/remote_files#createremotefile) API. * `CreateRemoteFile` only creates the metadata record; it does not upload the file bytes. A separate upload step is required. * Filenames must be unique per Asset. Duplicate filenames can conflict. * Uploads are not resumable. Treat each upload as a single request and handle retries on the client side. * Sift does not transcode video server-side; files play back exactly as uploaded. * Include duration, dimensions, and timestamp metadata where available. This metadata drives time-sync with telemetry in the File Viewer Panel. #### Stat #### Enum ### Panel Configurations Panel Configurations save and reuse a Panel's visualization setup. Configurations can be applied to any Run or Asset. **Compatibility with Explore (legacy)** Views from Explore (legacy) are automatically available as Panel Configurations in Explore. New Views created in Explore (legacy) continue to generate corresponding Panel Configurations. ### Panel export Export is available for Timeseries Panels only. Exports run in the background. **Limitations** * Nested Calculated Channels cannot be exported and are excluded. * Relative Time mode is not supported for export. ## Channels Channels are the individual telemetry signals available for plotting. They are listed in the Channels tab, organized in a Channel tree by default. ### Channel tab views ### Plotting Channels can be plotted by clicking or dragging from the Channels tab onto any Panel. A data source must be selected before Channels are available. ### Axis assignment Applies to the Timeseries Panel. Channels can be assigned to up to 8 Y-axes. Channels can be reassigned to a different axis by dragging the Channel entry in the Timeseries legend and selecting a target axis. ### Legend Group By Right-click the legend in a Timeseries Panel and select **Legend Group By** to control how the legend groups channel entries. ### Bulk axis and style assignment Simultaneous axis and style configuration for all Channels. Available in Timeseries and FFT Panels. ## Calculated Channels Calculated Channels are derived signals created by applying CEL expressions to raw Channel data. They appear in the Calculated Channels tab. ### Types ### Temporary Calculated Channel fields The following fields are available when creating a temporary Calculated Channel in Explore. For full Calculated Channel settings and behaviors, see [Calculated Channels settings](/documentation/reference/calculated-channel-settings). ## Runs ### Time alignment Time alignment synchronizes multiple Runs to a shared reference point (T-0) for direct comparison. The selected alignment applies to all Runs in the Panel. **Timeseries Panel shortcuts** The following shortcuts are available directly from the Timeseries Panel without opening Panel settings. ### Run from selection A new Run can be created from a specific time window within an existing Run plotted in Explore. ### Metrics Panel from selection A Metrics Panel can be created from a specific time window selected in an existing Time Series Panel. **Reorder rows:** Rows can be reordered by dragging a row's drag handle to a new position within the Panel. ## Annotations Annotations mark specific times or time ranges in a Run. They can be plotted on the Timeseries Panel only and used as T-0 alignment points for Run comparison. In Live mode, live Rules are not rendered; alerts appear as toast notifications. ### Annotation types Explore supports the following Annotation types. ### Annotation fields The following fields are available when creating or editing an Annotation. Available fields vary by Annotation type. ### Plot Annotations Use **Plot All** in the **Annotations** tab to plot every Annotation onto the Timeseries Panel. **Rule's folder**: **Plot All** does not plot Annotations inside a collapsed Rule folder. To plot the Annotations in a specific Rule folder regardless of its collapsed state, right-click the folder and select **Plot all Annotations**. This does not apply if the outer Annotation group containing the folder is itself collapsed. ## Dynamic URLs Use dynamic URLs to open Explore with preconfigured telemetry data. By navigating to the `/explore` route with query parameters, you can automatically load specific Runs or Assets, Channels, Panel types, and optional time ranges, allowing users to open the exact data needed for analysis without manual setup. For example, the following URL opens a Timeseries Panel with a single Channel on a single Run: ``` https://{domainName}/explore \ ?method=single \ &runs=runName \ &channels=channelName \ &panelType=timeseries ``` ### URL structure Use the `/explore` route with the required query parameter `method=single` to launch Explore with preconfigured data. Additional query parameters define Runs or Assets, Channels, Panel type, and optional time range. Construct the URL using the following format: ``` https://{domainName}/explore?method=single \ &runId={uuid1,uuid2,...} \ &runIds={uuid1,uuid2,...} \ &runs={runNameOrUUID1,runNameOrUUID2,...} \ &assetId={uuid1,uuid2,...} \ &assetIds={uuid1,uuid2,...} \ &assets={assetNameOrUUID1,assetNameOrUUID2,...} \ &channels={[prefix:]channelNameOrUUID,...} \ &channelId={[prefix:]uuid,...} \ &channelIds={[prefix:]uuid,...} \ &panelType=timeseries|table|histogram|fft|scatter-plot|geo-map|metrics \ &startTime=YYYY-MM-DDTHH:MM:SSZ \ &endTime=YYYY-MM-DDTHH:MM:SSZ ``` * **Format**: Line breaks and backslashes (`\`) are shown for readability. In actual use, the URL must be a single continuous string joined with `&`, without spaces or backslashes. * **Parameter order**: Parameters can appear in any order, but the URL must start with `domainName/explore?method=single`. * **Channel name matching**: Provide Channel names through `channels`. `channelId` and `channelIds` accept Channel UUIDs only. Channel names are matched case-insensitively. ### URL parameters **Calculated Channels aren't supported in dynamic URLs**: `channelId` and `channelIds` resolve by matching against Channels persisted on the selected Run. Calculated Channels aren't persisted to a Run's Channel list the same way, so a Calculated Channel UUID does not resolve through `channels`, `channelId`, or `channelIds`, even though the same Calculated Channel plots correctly when selected manually in Explore. Add Calculated Channels manually in Explore instead of passing their UUID in a dynamic URL. ### Channel axis assignment In the Timeseries Panel, Channels can be plotted on multiple Y-axes by adding an axis prefix before the Channel name or UUID. If no prefix is provided, the Channel plots on the default axis `L1`. Axis prefixes are case-sensitive and work with both Channel names and UUIDs. ### Scatter Plot Channel roles In the Scatter Plot Panel, assign each Channel to an axis or visual encoding using a role prefix before the Channel name or UUID: * Role prefixes are case-insensitive and work with both Channel names and UUIDs. * All prefixed Channels populate a single trace group. When a `color:` Channel is provided, points are colored with a Viridis gradient by default. * A Channel without a recognized prefix is treated as a plain name or UUID. Scatter Plot sharelinks use a single Run; if multiple Runs are selected, the first is used. ### Geo Map Channel roles In the Geo Map Panel, assign each Channel to a coordinate or visual encoding using a role prefix before the Channel name or UUID: * Role prefixes are case-insensitive and work with both Channel names and UUIDs. * All prefixed Channels populate a single coordinate set. * When a `color:` Channel is provided, points are colored with a Viridis gradient by default. * If no role prefixes are provided, the Geo Map Panel automatically detects latitude and longitude Channels by name. ### Channel selection by Panel type Each Panel type displays only the Channels it supports; Channels of an incompatible data type are ignored. For example, the Histogram, FFT, Scatter Plot, Geo Map, and Metrics Panels do not display string Channels, so a string Channel passed to one of them is dropped. The Histogram Panel displays a single Channel. If more than one Channel is provided, the first compatible Channel is used and a warning appears. # CEL expression Source: https://docs.siftstack.com/documentation/reference/expression-syntax Functions, operators, and Channel references for writing expressions using Sift's supported subset of CEL in Calculated Channels, Rules, and User-Defined Functions Use this page to look up CEL expression syntax in Sift. Expressions are written using a subset of Common Expression Language ([CEL](https://cel.dev)) and are used in Calculated Channels, Rules, and User-Defined Functions. Sift supports a subset of CEL data types and operators, not the full CEL specification. ## Channel references When configuring a Rule, Calculated Channel, or User-Defined Function, you select input Channels by name from the **Input Channels** selector. Sift automatically assigns each selected Channel a shorthand variable based on selection order: `$1` for the first Channel, `$2` for the second, `$3` for the third, and so on. Use these variables to reference the corresponding Channel in your expression. ## Operators The following table lists the CEL operators supported in Sift. Not all CEL operators are supported. ## Functions The **Expression Syntax** panel in the expression editor organizes functions into the following sections: ## Stateful functions Stateful functions compute values using data from preceding rows within a rolling time window of up to **10 minutes**. Use them to track trends, detect gradual changes, and compute time-based metrics across telemetry data. The following table lists all available stateful functions with expanded descriptions to help you choose the right function for your use case. ## File functions File functions allow Rules and Calculated Channel expressions to access data from files attached to an Asset or a Run. Once a file is loaded, you access specific values using bracket notation. The syntax depends on the file format. **Live Rules**: File functions are not supported in live Rule evaluation. The following table lists the available file functions: ### Supported file formats Files that can be referenced by the file functions must be in one of the following supported formats: **CSV**, **JSON**, **TXT**, or **YAML**. **File size**: The maximum file size per file is **10 MB**. ### Bracket notation Once a file is loaded, use bracket notation to access specific values. The syntax depends on the file format. #### JSON and YAML JSON and YAML files resolve to a map. Use bracket notation to index into keys. For nested objects, chain brackets. To access an item in a list, use a numeric index. #### CSV CSV files resolve to a column-oriented structure. Use the column name or column index (0-based) as the first bracket and a row number as the second. #### TXT TXT files resolve to a string literal. To use the value numerically, cast it with a function like `double()`. ## User-Defined Functions The User-Defined Functions section of the expression editor lists all named, reusable functions created across your organization. Call any function by name directly in your expression. To learn more, see [User-Defined Functions settings](/documentation/reference/user-defined-functions-settings). ## Behavior The following table describes known constraints and behaviors to be aware of when writing expressions in Sift. ## Related workflows * [Detect deviations automatically using Rules](/documentation/review/detect-deviations-automatically-using-rules) * [Create a derived signal](/documentation/transform/create-a-derived-signal) * [Reuse expression logic](/documentation/transform/reuse-expression-logic) # Families reference Source: https://docs.siftstack.com/documentation/reference/families-reference Core concepts and processes involved in creating and using Families. **Family** statistics compare signal behavior across a group of Runs, such as average pressure during firing or peak temperature spread across tests. At a high level, the pipeline involves finding the same event in each Run, cutting out the data around it, normalizing the samples to a common rate, and then computing a summary statistic across all those slices. To produce meaningful statistics, especially for use in Rules, you can view the process as a two-phase pipeline: **alignments and dynamic windows** select the slice of each Run to compare, and **bucketing and aggregation** collapse those slices into a single statistic series. This topic describes the core concepts and processes involved in producing meaningful Family statistics. ## Glossary * **Alignment**: A reference event (such an Annotation, Run start/end, or fixed timestamp) used to normalize Runs to a common time axis. * **Alignment point**: A single timestamped occurrence of an alignment within a Run. A Run with three of the same event would have three alignment points. * **Dynamic window**: A time slice with bounds defined as `alignment + offset`, so it resolves to a different actual window per Run. * **Dynamic window occurrence**: A concrete time slice produced by resolving a dynamic window against one Run's alignment points. A Run can produce multiple occurrences. * **Family statistic**: A time series summarizing a group of Runs, such as their mean signal or 3-sigma envelope. * **Bucket**: A fixed-width interval on the output rate's grid that holds one normalized value per occurrence. * **Aggregation**: The per-bucket reduction across occurrences (`avg`, `min`, `max`, `stdev`) that produces the Family statistic. * **`input_count`**: A diagnostic series reporting how many occurrences contributed to each bucket; low values flag unreliable statistics. ### How these concepts work together Producing a Family statistic follows a fixed sequence: 1. **Define an alignment (your reference event).** Choose the event that marks the moment of interest across all Runs, such as valve open or engine startup, to anchor each Run on a common time axis. 2. **Resolve alignment points (find every instance of that event).** For each Run, every occurrence of the alignment event gets a timestamp. A Run with three valve openings produces three alignment points. 3. **Define a dynamic window (the time slice you care about).** Specify window start and end as an alignment event plus an optional offset. This scopes the comparison to the portion of each Run relevant to the event of interest. 4. **Resolve dynamic window occurrences (one slice per event instance).** The dynamic window is applied to each Run's alignment points. Each valid combination of start and end alignment points produces one occurrence; a Run with multiple cycles contributes one occurrence per cycle. 5. **Bucket each occurrence (normalize sample rates).** A uniform bucket grid is applied to normalize occurrences sampled at different rates to a single value per bucket. 6. **Aggregate across occurrences (compute the summary statistic).** The selected aggregation (`avg`, `min`, `max`, `stdev`) is computed per bucket across all contributing occurrences, producing the final Family statistic series. 7. **Check `input_count` (verify enough data contributed).** Inspect the diagnostic series to identify buckets with sparse coverage, where spread statistics become unreliable. ## Aligning Runs To aggregate across Runs that occur at different absolute (UTC) times, each Run must first be normalized to a common time axis. An **Alignment** defines how. Aligning Runs alone is sufficient for plotting Family members and visually comparing their behavior, but statistical aggregation in Rules also requires scoping the comparison to the relevant duration. That scope is defined by a **Dynamic Window**. A Dynamic Window is defined by: * **T-0 alignment**: the anchor event the slice is centered on in relative time, such as a valve opening. * **Window start** and **window end**: the bounds of the slice, each defined as an alignment event with an optional offset. Because dynamic windows are defined relative to events rather than absolute time, the resolved window differs for each Run. Dynamic windows ### Multiple occurrences per Run The ability to set multiple alignment points within a single Run is in private preview and not yet available to all customers. Reach out to Sift support to get access. A single Run can contain more than one event of interest. A valve, for example, may open and close several times in the same Run. Each event may be represented by a separate **Alignment Point**. For example, a "Valve Open" alignment defined by an Annotation that exists on each opening resolves to an alignment point for each opening. When a Dynamic Window's bounds resolve against multiple alignment points, the window produces multiple **dynamic window occurrences** in the same Run, one per valid combination of bounds. Each occurrence contributes to the aggregate independently and is plotted as if it were a separate Run. Multiple dynamic window occurrences The remaining sections describe computation **per occurrence**. When a Run produces exactly one occurrence (the common case), "per occurrence" and "per Run" are equivalent. When a Run produces multiple occurrences, each is treated as an independent contributor. ## Bucketing and aggregation Family statistics are computed in two stages: each occurrence is bucketed to a common sample rate, then aggregated across occurrences, per bucket. ### Stage 1: Bucketing per occurrence The output rate determines a uniform bucket grid. Each occurrence is independently normalized to exactly one value per bucket, using one of three strategies based on its input rate relative to the output rate: Forward fill is experimental and not enabled by default. Reach out to Sift support to have it enabled for your organization. Bucketing exists to remove sample-rate bias from the aggregate. Without it, a Run sampled at 100 Hz contributes 100 samples per second of window while a Run sampled at 1 Hz contributes only 1. The Family statistic ends up weighted by sample rate rather than by Run, with the highest-rate contributors dominating. Bucketing normalizes every occurrence to a single value per bucket regardless of underlying sample rate, so each occurrence carries the same weight in the aggregate. ### Stage 2: Aggregation across occurrences With every occurrence contributing exactly one value per bucket, the selected aggregate (`avg`, `min`, `max`, `stdev`) is computed across occurrences, per bucket. The result is a single series at the output rate. Bucketing and aggregation pipeline The bucket-level aggregate treats real samples, forward-filled values, and within-bucket means as equivalent contributions. The `input_count` series reports how many occurrences are contributing to each bucket. When `input_count` drops, statistics like `stdev`, `min`, and `max` become unreliable because too few occurrences are contributing. This is most common at the trailing or leading edges of dynamic windows, where occurrences end or start at different relative times. ## Working with Family statistics in Rules * Choosing an output rate lower than the raw data rate smooths sensor noise before aggregation. The same approach can be applied to inputs within a Rule using the `avg($1, bucket(1s))` CEL function, which averages the input signal into 1-second buckets before evaluation. Comparing bucketed inputs against bucketed Family statistics prevents sensor noise from triggering false Rule violations. * The Family statistics preview is the most direct way to see how alignments, dynamic windows, and bucketing interact for a given configuration. # Authorization models settings Source: https://docs.siftstack.com/documentation/reference/manage/authorization-models-settings Settings, options, and behaviors for Role-Based Access Control (RBAC) and Attribute-Based Access Control (ABAC) in Sift. Sift access control uses two strategies: Role-Based Access Control (RBAC) and Attribute-Based Access Control (ABAC). RBAC is the default system. ABAC provides more granular control. ## RBAC vs ABAC The following table compares RBAC and ABAC to help you determine which model fits your organization's needs: **When to use ABAC**: Not all organizations need ABAC. RBAC is often easier to configure and manage. ABAC is not a one-size-fits-all solution. Most organizations will find RBAC sufficient and easier to manage. ## Role-Based Access Control (RBAC) Role-based access control (RBAC) is the default access control system in Sift. RBAC uses predefined roles and groups to manage user permissions across resources. RBAC sets the maximum permissions a user can have. ABAC can only further restrict access within that boundary. ### Roles RBAC uses four predefined roles that determine the level of access granted to users: * **Admin**: Full access to data, configuration settings, and user management. Admins can create and modify groups, manage users, and configure system settings. * **Editor**: Can view, edit, and write time series data and metadata. Editors have full data access but cannot manage users or system configuration. * **Collaborator**: Can view time series data and add metadata. Collaborators can annotate and tag data but cannot modify the underlying time series data. * **View-only**: Read-only access to time series data. View-only users can explore and analyze data but cannot make any changes. **Custom roles**: Custom roles in RBAC are not supported at this time. All organizations use these four predefined roles. For custom defined roles an organization needs to use ABAC. ### Role permissions The following table shows which permissions are available for each role. An `*` indicates that the role has that permission: ### Groups Groups are collections of users that share the same role and Asset access permissions. Groups simplify access management by allowing administrators to assign permissions to multiple users at once. Key characteristics of groups: * **Role assignment**: Each group is assigned one of the four predefined roles (Admin, Editor, Collaborator, or View-only). * **User membership**: Users can belong to one or more groups, inheriting permissions from all groups they belong to. * **Default groups**: Internal users (those with email addresses matching the organization's domain) are automatically added to a default group during sign-up. External users are assigned to a specified group during invitation. ### Asset access Asset access determines which resources (Runs, Channels, Reports, etc.) a group can access. Groups can be configured with: * **All assets**: Access to all resources in the organization. * **Specific assets**: Access restricted to a defined subset of Assets. This allows administrators to create groups with the same role but different data access. For example, you might have an "Engine Team - Editors" group with Editor role and access to Engine Assets, and a "Propulsion Team - Editors" group with Editor role and access to Propulsion Assets. ### How permissions work Permissions in RBAC are determined by a user's group memberships: 1. **Group role**: Each group has a role that defines what actions its members can perform. 2. **Asset access**: Each group has access to either all Assets or a specific subset of Assets. 3. **Combined permissions**: When a user belongs to multiple groups, they inherit the union of permissions from all groups. For example, if a user belongs to a group with Editor role and access to Engine Assets, and another group with Collaborator role and access to Propulsion Assets, they will have Editor permissions on Engine Assets and Collaborator permissions on Propulsion Assets. ## Attribute-Based Access Control (ABAC) ABAC controls access using attributes assigned to users and resources. While RBAC uses fixed roles to set the boundary of what a user can do, ABAC evaluates attribute-based policies to further restrict access within that boundary. **How RBAC and ABAC work together**: ABAC does not replace RBAC. RBAC sets the maximum permissions a user can have. ABAC can only further restrict access within that boundary. An ABAC policy cannot grant permissions that the user's RBAC role forbids. ### User attributes User attributes are key-value pairs that describe who a user is. You can assign attributes directly in Sift or sync them from an Identity Provider (IdP). ### Resource attributes Resource attributes are key-value pairs that describe Sift resources. ABAC uses them alongside user attributes to evaluate policies. #### Supported resource types You can assign attributes to the following resource types: * **Assets** * **Channels** * **Runs** #### Access inheritance ABAC enforces access inheritance between related resources: * **Channels inherit from their parent Asset.** If a user is denied an action on an Asset, the same action is denied on all of that Asset's Channels, even if a separate policy allows it on the Channel. The Asset-level decision always wins. * **Runs check Asset access only for `viewData`.** To view telemetry data on a Run, the user must have `viewData` access to at least one of the Run's associated Assets. If all associated Assets deny `viewData`, the Run is denied too. Other actions on Runs (such as `editDetails` or `archive`) are evaluated on the Run alone. #### Attribute data types The following table describes the supported data types for attributes: **Best practice**: Use Enum instead of Boolean for statuses like employment type. It is easier to add a third value (for example, "Part-Time") to an Enum than to restructure Boolean logic later. #### Attribute key uniqueness Attribute key names must be unique across your organization. You cannot create two attributes with the same name, even if they have different data types. ### Policies Policies define the logic that governs access. #### Evaluation model Sift evaluates access in two layers: ABAC uses a **default-deny** model. For a user to access an ABAC-controlled resource, there must be at least one `allow` policy that matches. If no policy matches, access is denied. **Initial setup**: When ABAC is first enabled for an organization, a blanket allow policy is typically configured so that existing access is preserved. Specific `deny` policies are then added to restrict sensitive resources. Without a blanket allow, all non-admin users lose access to ABAC-controlled resources. #### Precedence When multiple policies match, Sift resolves them using strict precedence: #### Actions Every policy must define which actions are allowed or denied. The `viewDetails` action serves as a prerequisite for all other operations. If a user cannot `viewDetails` on a resource, all other actions on that resource are automatically denied. The following table lists all available actions: #### Policy settings The following table describes the settings available when creating or editing a policy: #### Operators by attribute data type The following table lists the available operators for each attribute data type: **User group operators**: When the attribute type is **User group**, only Enum Set operators are available (`Contains`, `Contains All`, `Contains Any`, `Intersects With`, `Is Empty`). The `Intersects With` operator compares a user group's attribute against a resource attribute, enabling dual-match conditions without specifying fixed values. #### Admin bypass By default, users with the Admin RBAC role bypass ABAC policy evaluation entirely. Admin access is governed solely by RBAC. ## Best practices ### Plan your policy Define the scope before configuring anything. * **Subject**: Who is affected (internal staff, contractors, systems)? * **Object**: Which resources are being protected? * **Action**: Should the policy allow or deny access? ### Organize with groups Apply policies to user groups, not individual accounts. Create dedicated groups for specific needs (for example, a Vendor-Access-Group). This simplifies auditing because you can remove a user from the group instead of updating multiple policies. ### Choose the right attribute type ### Use dual-match conditions Require matching attributes on both the user and the resource. For example, to restrict access to Artemis Mission assets, create an `intersect` policy with two conditions: 1. User has `Mission = Artemis` 2. Resource has `Mission = Artemis` Access is granted only when both conditions are satisfied. ### Naming conventions * **PascalCase**: `EmploymentStatus`, `ClearanceLevel` * **Subject-property pattern**: `UserDepartment`, `ResourceProject` * **Boolean prefixes**: `IsActive`, `HasMFA` * **Avoid redundancy**: Use `ClearanceLevel`, not `ClearanceLevelInteger` ## FAQs ### What happens if I don't assign attributes to a resource? If no ABAC policies target a resource, access depends on your policy configuration. With a blanket allow policy in place, the resource is accessible to anyone whose RBAC role allows it. Without a blanket allow, unmatched resources are denied by default. ### Can I restrict access to specific Channels? Yes. You can assign resource attributes to individual Channels and Runs, not just Assets. For example, you can allow a user to see an Asset but deny access to a specific sensitive Channel within that Asset. Note that the reverse also applies: if access to an Asset is denied, all Channels belonging to that Asset are also denied. ### What happens if a user matches multiple policies? Sift prioritizes security: if any matching `deny` policy denies access, access is denied immediately, regardless of any `allow` policies. Access is only granted when at least one `allow` matches and no `deny` applies. ## Behavior The following table describes known constraints and behaviors to be aware of when working with authorization models in Sift: # Identity Provider (IdP) settings Source: https://docs.siftstack.com/documentation/reference/manage/idp-settings Settings, options, and behaviors for Identity Provider (IdP) integration in Sift. Sift supports the integration of external Identity Providers (IdPs) to manage users and groups. When changes occur in the IdP, such as creating, deleting, or renaming users or groups, or modifying group memberships, those changes are synchronized to Sift. ## Supported Identity Providers Sift supports Identity Providers that use push-based provisioning to create and update users and groups in Sift based on the current configuration in the IdP. The following IdPs support push-based provisioning and have been verified to work with Sift: **Pull-based provisioning**: Sift only supports IdPs that use push provisioning. IdPs that require pull-based provisioning, such as Google Workspace, require custom integration work. ## SCIM provisioning SCIM provisioning in Sift synchronizes users and groups from your Identity Provider into Sift. When the IdP creates, deletes, or updates a user, a group, or a group's membership, those changes are applied in Sift during the next scheduled sync. ## Behavior The following table describes known constraints and behaviors to be aware of when working with Identity Providers in Sift. # Metadata settings Source: https://docs.siftstack.com/documentation/reference/manage/metadata-settings Settings, options, and behaviors for Metadata in Sift, including supported resource types such as Runs, Campaigns, and Annotations. Metadata in Sift allows organizations to define structured key-value pairs that can be applied to any supported resource in the workspace, creating a consistent taxonomy for organizing, categorizing, and filtering data. Each Metadata key is defined once at the organization level and bound to a specific data type, ensuring values are used consistently across projects while enabling advanced search and filtering. ## Resources that support Metadata The following Sift resources support user-defined Metadata: * Runs, * Assets, * Annotations, * Rules, * Reports, * Report Templates, * Campaigns, * Calculated Channels, and * User-defined Functions. ## Settings The following table describes the settings available when creating a Metadata key. ## Data types Metadata values support the following data types. ## Behavior The following table describes known constraints and behaviors to be aware of when working with Metadata in Sift. # User Management settings Source: https://docs.siftstack.com/documentation/reference/manage/user-management-settings Settings, options, and behaviors for User Management in Sift. The User Management section provides tools for managing access to Sift within an organization. It contains three tabs: **Users**, **Groups**, and **Syncs**, which allow administrators to review users, assign permissions, control access to data, and audit Identity Provider sync history. ## Tabs ### Users The **Users** tab lists all members of the organization. ### Groups The **Groups** tab lists all user groups within the organization. #### Group roles Each group is assigned one of the following roles, which determine the level of access granted to its members. For a full breakdown of permissions per role, see [Authorization models settings](/documentation/reference/manage/authorization-models-settings#roles). ### Syncs The **Syncs** tab allows administrators to review historical Identity Provider syncs and audit user and group changes over time. ## Behavior The following table describes known constraints and behaviors to be aware of when working with User Management in Sift. # Webhook settings Source: https://docs.siftstack.com/documentation/reference/manage/webhooks-settings Settings, options, and behaviors for Webhooks in Sift. Webhooks in Sift enable sending real-time notifications to external systems when specific events occur, such as when a Rule is violated or resolved. Each webhook includes a trigger event, a customizable payload, and a destination URL that receives the data via an HTTP POST request. Webhooks only fire during live Rule evaluations and do not execute when Rules are run on historical data. ## Settings The following table describes each setting available when creating or editing a webhook. ## Trigger event types When creating a webhook, you must select a trigger event type. The following trigger event type is available: ## Built-in variables Each trigger event type includes a set of built-in variables available when creating or editing a webhook. These variables can be used to customize the webhook payload with dynamic, event-specific data. ### Rule Violation The following table lists the built-in variables available for the Rule Violation trigger event type. ## Webhook payloads Webhook payloads define the content sent to the destination URL when a webhook fires. Payloads are fully customizable and can be formatted as either plain text or JSON. Each payload can include built-in variables specific to the selected trigger event type, allowing dynamic insertion of relevant data such as Rule names, statuses, and timestamps. Sift provides predefined payload templates for services like Slack, OpsGenie, Jira, and PagerDuty. These can be selected from the **Payload config template** list during webhook creation or editing. The payload editor supports control flow, including if-else logic for dynamic formatting. For example: ```json theme={null} { "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": "{{if eq .Status \"resolved\"}}:white_check_mark: Resolved{{else}}:bangbang: *Alert - {{.Status}}*{{end}}" } } ] } ``` ## Correlate violation and resolution events Violating and resolving a Rule each fire a separate Rule Violation webhook event, with `{{.Status}}` set to `violated` or `resolved`. Both events are tied to the same underlying Annotation: the violation opens the Annotation, and the resolution closes it. Each event has its own `{{.EventId}}`, so the violation and resolution events for the same occurrence do not share an `{{.EventId}}` or a payload `deduplication_key` derived from it. To correlate the violation and resolution events for the same occurrence, key off the associated Annotation together with `{{.Status}}` instead of `{{.EventId}}`. ## Custom HTTP headers When configuring a webhook, you can optionally define HTTP headers to customize how the receiving system handles the request. These headers are sent along with the webhook payload. ## Secure webhooks Sift supports secure webhook delivery using HMAC-SHA256 signatures. These signatures ensure the webhook was sent by Sift and has not been tampered with in transit. Webhooks are only signed if your Sift environment has a webhook signing key configured. If no signing key exists, webhooks will not include an `X-Sift-Signature` header and should not be trusted for secure operations. Once a signing key is configured, each outgoing webhook will include a signature header computed using the following formula: ``` HMAC_SHA256(signing_key, sent_at + raw_payload) ``` The `sentAt` value must be present in the payload to successfully validate the signature. This value is not included automatically. You must explicitly add it using `{{.SentAt}}` in your webhook payload template. Without it, signature verification will fail. ## Role-based access control Webhooks follow Sift's standard RBAC model. The following table describes the permissions available for each role. **Insufficient permissions**: Unauthorized users who attempt to access restricted pages by entering the URL directly will be redirected to the Manage page and shown a warning indicating insufficient permissions. ## Behavior The following table describes known constraints and behaviors to be aware of when working with Webhooks in Sift. # Naming conventions and limits Source: https://docs.siftstack.com/documentation/reference/naming-rules Character limits, allowed characters, and mutability behavior for Asset, Channel, Run, and other Sift entity names. Names in Sift are often used as identifiers in the API and workflow pipelines, not just as display labels. Understanding the constraints for each entity type helps you avoid failures and plan for changes. ## General behaviors ### Case sensitivity Asset names are stored with their original casing. Sift maintains a lowercase index to support case-insensitive lookups, and the filtering API supports both `caseSensitive: true` and `caseSensitive: false` modes. ### Name reuse after archiving For most entities, uniqueness constraints apply only to non-archived entities. Once an entity is archived, its name can be reused by a new entity. Channel names are scoped per Asset, meaning two different Assets can have a Channel with the same name. Within a single Asset, a Channel is uniquely identified by the combination of name, data type, and unit. A Channel with the same name but a different data type or unit is treated as a distinct Channel. ### Whitespace trimming Asset and Tag names have leading and trailing whitespace trimmed before storage. ## Assets `asset_name` is a required field in the ingestion API, data import API, and Channel schema API. If you create an Asset under one name, every external system sending data to that Asset by name must use that exact name. ## Channels | Rule | Detail | | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | | Max length | 255 bytes | | Allowed characters | ASCII only: no Unicode | | Prohibited characters | `"` `\` `` ` `` `~` `\|` and the ASCII Information Separator characters: File Separator, Group Separator, Record Separator, and Unit Separator | | Spaces | Allowed | | Mutability | Immutable: only description, units, metadata, and active status can be updated | Channel names function as identifiers in the ingestion pipeline. Like Asset names, changing a Channel name is not supported. Any external system referencing the Channel by name would require updates. ### Channel name structure Explore parses a Channel name into a visual hierarchy in the [Channel tree](/documentation/reference/explore-settings#channel-tab-views) using the * **Channel Name Delimiter**, * **Channel Name Prefix Delimiter**, and * **Channel Leaf Keywords** settings. See [General settings](/documentation/reference/explore-settings#general-settings) to configure these settings. Channel names often end in a trailing word, such as `value`, that designates the stored reading but does not add context to the Channel tree, so with * **Channel Name Delimiter** set to `.`, * **Channel Name Prefix Delimiter** set to `/`, and * **Channel Leaf Keywords** including `value`, the Channel name `Some/Folder/actual.channel.name.value` displays in the Channel tree as: ``` Some Folder actual channel name ``` ## Calculated Channels ## Runs ## Annotations ## Campaigns ## Tags ## Flows # Report chart display options Source: https://docs.siftstack.com/documentation/reference/report-chart-display-options Strip charts, merged charts, Log Viewer, and keyboard navigation in Reports When you open a Rule in a Report, the chart section displays the channel telemetry associated with the Rule and its Annotations. If the Rule includes more than one channel, Sift determines the default chart format based on the channel types. You can switch between formats using the controls in the chart interface. ## Chart formats ## Switching between formats * To merge strip charts into a single chart: click **Merge charts**. * To split a merged chart back into strip charts: click **Split charts**. ## Log channel behavior If a Rule includes a log-type channel, the chart and the Log Viewer appear together in the Rule view. The Log Viewer shows the exact log entries that caused the Rule's condition to evaluate to `true`; for example, when an expression like `contains(sys_log, "failure")` fires. When a Rule includes both numeric and log channels, the time-series chart and the Log Viewer are displayed side by side so you can examine both the quantitative data and the log context at the same time. ## Keyboard navigation To move through Rules in a Report without using the mouse: * Press `Shift` + `←` to go to the previous Rule. * Press `Shift` + `→` to go to the next Rule. ## Edge cases and limitations * The merge option applies to numeric channels only. Log channels always appear in the Log Viewer regardless of whether charts are merged or split. * If a Rule includes only one channel, it is displayed as a single chart with no strip chart or merge option. ## Related workflows * [Detect and review issues in a Run](/documentation/review/detect-and-review-issues-in-a-run) # Report Templates reference Source: https://docs.siftstack.com/documentation/reference/report-templates-reference Apply the same checks to every Run automatically with a Report Template A Report Template applies the same set of Rules to a Run automatically, so you don't select them each time you generate a Report. Use a Report Template when you review the same type of Run repeatedly, or want your team to apply a consistent set of checks without remembering which Rules to include. For more information, see [Set up a repeatable review checklist](/documentation/review/set-up-a-repeatable-review-checklist). ## Report Template fields ## Rules The **Rules** section of a Report Template lists the Rules included in it. ### Add Rules to a template Select **+ Add Rules** to open a picker with the same columns as the Rules table, plus filters and a checkbox to select each Rule. ## Metadata Report Templates support user-defined metadata. Metadata is searchable and can be used to filter Report Templates in lists. See [Organize resources with Metadata](/documentation/manage/organize-and-filter-resources-with-metadata) for steps on adding metadata to a Report Template. ## Related workflows * [Set up a repeatable review checklist](/documentation/review/set-up-a-repeatable-review-checklist) * [Detect and review issues in a Run](/documentation/review/detect-and-review-issues-in-a-run) * [Detect deviations automatically using Rules](/documentation/review/detect-deviations-automatically-using-rules) # Reports reference Source: https://docs.siftstack.com/documentation/reference/reports-reference Fields, statuses, and settings for Reports in Sift A Report evaluates one or more Rules against a specific Run and collects the results in one place. Use a Report when you want to run detection logic against a completed Run and review the flagged issues. To review multiple Runs together, add their Reports to a [Campaign](/documentation/reference/campaigns-reference). ## Report fields ## Rule review states Each Rule in a Report has a review state derived from the state of its Annotations. Select a state button at the top of the Rules list to filter Rules by that state. ## Archiving Reports Reports can be archived but not deleted. Archiving removes a Report from the default view without destroying its data. ## Related reference topics * [Rule settings](/documentation/reference/rule-settings) * [Annotations reference](/documentation/reference/annotations-reference) * [Campaigns reference](/documentation/reference/campaigns-reference) * [Report chart display options](/documentation/reference/report-chart-display-options) ## Related workflows * [Detect and review issues in a Run](/documentation/review/detect-and-review-issues-in-a-run) * [Set up a repeatable review checklist](/documentation/review/set-up-a-repeatable-review-checklist) * [Track a multi-Run review campaign](/documentation/review/track-a-multi-run-review-campaign) # Rules reference Source: https://docs.siftstack.com/documentation/reference/rule-settings Settings, options, and behaviors for Rules in Sift. A Rule defines logical conditions used to automatically evaluate telemetry data from one or more Channels during a Run. Built using the [Common Expression Language (CEL)](https://cel.dev), Rules can identify behaviors, anomalies, or thresholds in live or historical data streams. ## Capabilities Rules can be created, previewed, and managed either through the Sift UI or programmatically using the Sift API. The following table describes the key capabilities of Rules: ## Rules vs Ad Hoc Rules All Rules in Sift share the same CEL-based evaluation engine and structure. However, the way a Rule is created determines how it is managed, who can see it, and how it integrates into your workflow. ### Comparison The following table compares Rules and Ad Hoc Rules: ### When to use Rules Use Rules for detection logic that: * Will be reused across multiple Runs. * Needs to be updated, versioned, or reviewed over time. * Should be visible and managed by your team in the Sift UI. * Will be included in a Report Template for standardized reviews. Rules are the right default for most use cases. ### When to use Ad Hoc Rules Use Ad Hoc Rules when: * You are running automated evaluations in a CI/CD pipeline. * The Rule is ad hoc and does not need to persist in the UI. * You are generating Annotations programmatically via the API. #### API reference The following table lists the API endpoints for working with Ad Hoc Rules. The API uses the term `isExternal` for legacy reasons. This maps to Ad Hoc Rules in the Sift UI. ### Batch request atomicity `Batch[Verb]Rules` requests (for example, [BatchUpdateRules](/api-reference/ruleservice/batchupdaterules), `BatchArchiveRules`) are atomic: if any Rule in the request fails, Sift does not apply the request to any Rule in that batch. ## Live Rules Live Rules evaluate expressions against telemetry data as it streams into Sift in real time. They are continuously evaluated as data is received from Assets and can also be re-evaluated on historical data when a specific Run is selected. Live Rule evaluation is not enabled by default. To evaluate a Rule in real time, turn on **Enable Live Rule Evaluation** on the Rule. Without it, the Rule only evaluates when you run a Report. Programmatically, this corresponds to the `is_live_evaluation_enabled` field on [BatchUpdateRules](/api-reference/ruleservice/batchupdaterules). ### Live Rules and Reports Live Rules that do not generate any Annotations during the original evaluation are not linked to the Report and will not be included if the Report is rerun. To evaluate a Live Rule that was missed, generate a new Report on the Run and select the Rule manually. ### Rule evaluation state scoping A Live Rule keeps separate evaluation state for data sent with a Run ID and data sent without one. Data sent without a Run ID is only ever compared against other data sent without a Run ID. These two evaluation states stay isolated: comparisons for data without a Run ID never include data associated with a Run, and a Run's evaluation never includes data sent without one. If no data without a Run ID arrives for one hour, Sift drops that evaluation state. The next data point without a Run ID starts a new comparison instead of comparing against the earlier value. Because of this scoping, a Rule evaluated at the Asset level only evaluates data sent without a Run ID. It can't evaluate data that's associated with a Run — if a telemetry stream moves in and out of Runs, an Asset-level Rule only evaluates the portions sent without a Run ID. If your telemetry stream moves in and out of Runs, resend the current value without a Run ID right after a Run ends to keep the no-Run evaluation state current. # Runs reference Source: https://docs.siftstack.com/documentation/reference/runs-reference File attachments and Run management in Sift A Run is a defined time window during which telemetry is captured from one or more Assets. Runs provide the primary time context for organizing and analyzing telemetry. ## Concurrent Runs Multiple Runs of the same Asset can be active simultaneously. Each data point is owned by the Run that recorded it, so concurrent Runs on the same Asset do not collide even when they write to the same channel name at the same timestamp. This is the recommended pattern for parallel test sessions or CI workloads: 1. Create one Asset for the system under test (for example, `e1-sim`). 2. Start one Run per session, branch, or job. Name or tag each Run to make it identifiable later. For example, with a git SHA or CI job ID. ### Asset view behavior when no Run is selected When viewing an Asset in Explore without selecting a specific Run, Sift surfaces the most recently received value across all Runs. To isolate the data from a particular session, select that Run explicitly from the Run picker. ## File attachments Files can be attached to a Run as supplemental metadata. Attachments do not modify the Run or its telemetry. ### Supported file types ### Size limits ### Update a file attachment You can't update the contents of an existing file attachment in place. To replace a file's contents, remove the outdated file and attach the new one. ### Common operations ## Related workflows * [Import data from a file](/documentation/ingest/data-import/import-data-from-a-file) * [Export data from a Run](/documentation/export/export-data-from-a-file) # Client library reference Source: https://docs.siftstack.com/documentation/reference/stream/client-library-reference Installation, imports, and complete code examples for the Sift Python, Go, and Rust client libraries Sift provides official client libraries for: * [Python](#python) * [Go](#go) * [Rust](#rust) All libraries use ingestion-config-based streaming over gRPC. For the full protocol buffers reference, see the [gRPC API reference](/api/reference/protocol-buffers/index). The Python client library is named `sift_client` and is imported into your own code. It is not a command-line tool. For a standalone command-line tool, see the [Sift CLI](/documentation/cli/sift-cli) (`sift-cli`). **`sift_client` vs. `sift_py`**: Use `sift_client` for Python integrations. `sift_py` is deprecated and receives only critical bug fixes. ## Before you begin * **API key**: You need a Sift API key to authenticate requests. To create one, go to **Sift** > your profile icon > **Manage** > **API Keys** > **+ Create API Key**. For full steps, see [Create an API key](/documentation/manage/set-up-api-access). * **gRPC URI**: Your gRPC endpoint is shown on the **API Keys** page in Sift, in the **gRPC API URL** field. * **REST URI**: Your REST endpoint is shown on the same page, in the **REST API URL** field. Required by the Python client. In the code examples below, these values are read from environment variables (`SIFT_API_KEY`, `SIFT_URI`, `BASE_URI`). Set them before running any example. ## Python ### Install ```bash theme={null} pip install sift-stack-py'[sift-stream]' ``` ### Resources * [sift\_client documentation](https://sift-stack.github.io/sift/python/latest/reference/sift_client/) * [Full code example](https://github.com/sift-stack/sift/tree/main/python/examples/ingestion-tutorial) * [Repository](https://github.com/sift-stack/sift/tree/main/python) * [PyPI package](https://pypi.org/project/sift-stack-py/) ### Imports ```python theme={null} import asyncio import random from datetime import datetime, timezone from sift_client import SiftClient, SiftConnectionConfig from sift_client.sift_types import RunCreate from sift_stream_bindings import ( ChannelConfigPy, ChannelDataTypePy, ChannelValuePy, FlowConfigPy, FlowPy, IngestionConfigFormPy, TimeValuePy, ValuePy, ) ``` ### Data source ```python theme={null} async def data_source(): start = asyncio.get_event_loop().time() while asyncio.get_event_loop().time() - start < 60: await asyncio.sleep(0.5) yield datetime.now(timezone.utc), random.uniform(0, 10) ``` ### Ingestion config ```python theme={null} ASSET_NAME = "NostromoLV426" FLOW_NAME = "velocity-reading" CONFIG_KEY = "nostromo-lv-426-config-v1" flow_config = FlowConfigPy( name=FLOW_NAME, channels=[ ChannelConfigPy( name="mainmotor.velocity", unit="m/s", data_type=ChannelDataTypePy.Double, description="Main motor velocity", enum_types=[], bit_field_elements=[], ), ], ) ingestion_config = IngestionConfigFormPy( asset_name=ASSET_NAME, client_key=CONFIG_KEY, flows=[flow_config], ) ``` ### Connect, create a Run, and stream data ```python theme={null} async def main(): connection_config = SiftConnectionConfig( api_key="your-api-key", grpc_url="your-grpc-url", rest_url="your-rest-url", ) client = SiftClient(connection_config=connection_config) run = RunCreate(name=f"[{ASSET_NAME}].run", client_key=f"{CONFIG_KEY}.run") async with await client.async_.ingestion.create_ingestion_config_streaming_client( ingestion_config=ingestion_config, run=run, ) as ingest_client: async for timestamp, velocity in data_source(): await ingest_client.send( FlowPy( flow_name=FLOW_NAME, timestamp=TimeValuePy.from_timestamp_millis(int(timestamp.timestamp() * 1000)), values=[ ChannelValuePy(name="mainmotor.velocity", value=ValuePy.Double(velocity)), ], ) ) if __name__ == "__main__": asyncio.run(main()) ``` **Backwards compatibility** For a given `client_key`, adding new flows and channels is a safe and backwards compatible operation. Existing flows and channels should not be modified; this type of change is not backwards compatible and will lead to unexpected behavior. ## Go ### Install ```bash theme={null} go get github.com/sift-stack/sift/go ``` ### Resources * [Go documentation](https://pkg.go.dev/github.com/sift-stack/sift/go) * [Full code example](https://github.com/sift-stack/sift/tree/main/go/examples/ingestion) * [Repository](https://github.com/sift-stack/sift/tree/main/go) ### Imports ```go theme={null} package main import ( "context" "fmt" "log" "math/rand" "os" "time" "github.com/sift-stack/sift/go/gen/sift/common/type/v1" ingestv1 "github.com/sift-stack/sift/go/gen/sift/ingest/v1" "github.com/sift-stack/sift/go/gen/sift/ingestion_configs/v1" "github.com/sift-stack/sift/go/gen/sift/runs/v2" "github.com/sift-stack/sift/go/grpc" "google.golang.org/protobuf/types/known/timestamppb" ) ``` ### Data source ```go theme={null} func dataSource() <-chan dataPoint { dataChannel := make(chan dataPoint) go func() { rng := rand.New(rand.NewSource(time.Now().UnixNano())) duration := 60 * time.Second start := time.Now() for time.Since(start) < duration { dataChannel <- dataPoint{ Timestamp: time.Now(), Value: rng.Float64(), } time.Sleep(500 * time.Millisecond) } }() return dataChannel } ``` ### Flow and channel config ```go theme={null} func config() []*ingestion_configsv1.FlowConfig { return []*ingestion_configsv1.FlowConfig{ { Name: "velocity_reading", Channels: []*ingestion_configsv1.ChannelConfig{ { Name: "mainmotor.velocity", Unit: "km/hr", Description: "vehicle speed", DataType: typev1.ChannelDataType_CHANNEL_DATA_TYPE_DOUBLE, }, }, }, } } ``` ### Get or create ingestion config ```go theme={null} func getOrCreateIngestionConfig( ctx context.Context, grpcChannel grpc.SiftChannel, assetName, clientKey string, ) (*ingestion_configsv1.IngestionConfig, error) { svc := ingestion_configsv1.NewIngestionConfigServiceClient(grpcChannel) listRes, err := svc.ListIngestionConfigs(ctx, &ingestion_configsv1.ListIngestionConfigsRequest{ Filter: fmt.Sprintf("client_key == '%s'", clientKey), }) if err != nil { return nil, err } if listRes != nil && len(listRes.IngestionConfigs) > 0 { return listRes.IngestionConfigs[0], nil } createRes, err := svc.CreateIngestionConfig(ctx, &ingestion_configsv1.CreateIngestionConfigRequest{ AssetName: assetName, ClientKey: clientKey, Flows: config(), }) if err != nil { return nil, err } return createRes.IngestionConfig, nil } ``` ### Create a Run ```go theme={null} func createRun( ctx context.Context, grpcChannel grpc.SiftChannel, runName string, ) (*runsv2.Run, error) { svc := runsv2.NewRunServiceClient(grpcChannel) ts := timestamppb.Now() createRes, err := svc.CreateRun(ctx, &runsv2.CreateRunRequest{ Name: fmt.Sprintf("[%s].%d", runName, ts.Seconds), StartTime: ts, }) if err != nil { return nil, err } return createRes.Run, nil } ``` ### Main function ```go theme={null} const ( assetName = "NostromoLV426" clientKey = "nostromo-lv-426-config-v1" ) func main() { ctx := context.Background() grpcChannel, err := grpc.UseSiftChannel(ctx, grpc.SiftChannelConfig{ Uri: os.Getenv("SIFT_URI"), Apikey: os.Getenv("SIFT_API_KEY"), }) if err != nil { log.Fatalln(err) } ingestionConfig, err := getOrCreateIngestionConfig(ctx, grpcChannel, assetName, clientKey) if err != nil { log.Fatalln(err) } log.Printf("initialized ingestion config %s\n", ingestionConfig.ClientKey) run, err := createRun(ctx, grpcChannel, assetName) if err != nil { log.Fatalln(err) } log.Printf("initialized run %s\n", run.Name) siftStream, err := ingestv1.NewIngestServiceClient(grpcChannel).IngestWithConfigDataStream(ctx) if err != nil { log.Fatalln(err) } dataStream := dataSource() for data := range dataStream { req := &ingestv1.IngestWithConfigDataStreamRequest{ IngestionConfigId: ingestionConfig.IngestionConfigId, RunId: run.RunId, Flow: "velocity_reading", Timestamp: timestamppb.New(data.Timestamp), ChannelValues: []*ingestv1.IngestWithConfigDataChannelValue{ {Type: &ingestv1.IngestWithConfigDataChannelValue_Double{Double: data.Value}}, }, EndStreamOnValidationError: false, } if err := siftStream.Send(req); err != nil { log.Fatalln(err) } log.Println("ingested a velocity_reading flow") } if _, err := siftStream.CloseAndRecv(); err != nil { log.Fatalln(err) } log.Println("done.") } ``` ## Rust ### Install ```bash theme={null} cargo add sift_rs rand pbjson_types chrono tokio_stream cargo add tokio --features full ``` **Tokio** Tokio is required to work with `sift_rs`; it is the runtime that [tonic](https://docs.rs/tonic/latest/tonic/) relies on. The Tokio runtime flavor to use is dependent on your requirements. ### Resources * [sift\_rs documentation](https://docs.rs/sift_rs/0.1.0-rc.2/sift_rs/) * [Full code example](https://github.com/sift-stack/sift/tree/main/rust/examples/ingestion) * [Repository](https://github.com/sift-stack/sift/tree/main/rust) ### Imports ```rust theme={null} use chrono::{DateTime, Utc}; use pbjson_types::Timestamp; use rand::Rng; use sift_rs::{ gen::sift::{ common::r#type::v1::ChannelDataType, ingest::v1::{ ingest_service_client::IngestServiceClient, ingest_with_config_data_channel_value::Type, IngestWithConfigDataChannelValue, IngestWithConfigDataStreamRequest, }, ingestion_configs::v1::{ ingestion_config_service_client::IngestionConfigServiceClient, ChannelConfig, CreateIngestionConfigRequest, FlowConfig, IngestionConfig, ListIngestionConfigsRequest, }, runs::v2::{run_service_client::RunServiceClient, CreateRunRequest, Run}, }, grpc::{use_sift_channel, SiftChannel, SiftChannelConfig}, }; use std::{ env, error::Error, sync::mpsc::{channel, Receiver}, thread, time::{Duration, Instant}, }; ``` ### Data source ```rust theme={null} pub fn data_source() -> Receiver<(DateTime, f64)> { let (tx, rx) = channel(); thread::spawn(move || { let duration = Duration::from_secs(60); let start = Instant::now(); let mut rng = rand::thread_rng(); while Instant::now().duration_since(start) < duration { tx.send((Utc::now(), rng.gen_range(0.0..100.0))).unwrap(); thread::sleep(Duration::from_millis(500)); } }); rx } ``` ### Channel and flow config ```rust theme={null} pub fn channel_configs() -> Vec { vec![FlowConfig { name: String::from("velocity_reading"), channels: vec![ChannelConfig { name: String::from("mainmotor.velocity"), unit: String::from("km/hr"), description: String::from("vehicle speed"), data_type: ChannelDataType::Double.into(), ..Default::default() }], }] } ``` ### Get or create ingestion config ```rust theme={null} async fn get_or_create_ingestion_config( grpc_channel: SiftChannel, asset_name: &str, client_key: &str, ) -> Result> { let mut svc = IngestionConfigServiceClient::new(grpc_channel); let list_res = svc .list_ingestion_configs(ListIngestionConfigsRequest { filter: format!("client_key == '{client_key}'"), ..Default::default() }) .await?; if let Some(ingestion_config) = list_res.into_inner().ingestion_configs.first().cloned() { return Ok(ingestion_config); } let req = CreateIngestionConfigRequest { flows, asset_name: String::from(asset_name), client_key: String::from(client_key), ..Default::default() }; let create_res = svc.create_ingestion_config(req).await?; let ingestion_conf = create_res .into_inner() .ingestion_config .ok_or("expected ingestion config")?; Ok(ingestion_conf) } ``` ### Create a Run ```rust theme={null} async fn create_run(grpc_channel: SiftChannel, run_name: &str) -> Result> { let mut svc = RunServiceClient::new(grpc_channel); let ts = Utc::now(); let create_req = CreateRunRequest { name: format!("[{}].{}", run_name.to_string(), ts.timestamp()), start_time: Some(Timestamp::from(ts)), ..Default::default() }; let create_res = svc.create_run(create_req).await?; let run = create_res.into_inner().run.expect("expected run"); Ok(run) } ``` **Run metadata** `CreateRunRequest` supports additional metadata fields such as `description`, `tags`, `client_key`, and `stop_time`. For the full list of available fields, see the [`CreateRunRequest` documentation in sift\_rs](https://docs.rs/sift_rs/latest/sift_rs/gen/sift/runs/v2/struct.CreateRunRequest.html). These fields are also documented in the [Run API reference](/api/reference/protocol-buffers/runs). ### Main function ```rust theme={null} pub const ASSET_NAME: &str = "NostromoLV426"; pub const CLIENT_KEY: &str = "nostromo-lv-426-config-v1"; #[tokio::main] async fn main() -> Result<(), Box> { let grpc_channel = use_sift_channel(SiftChannelConfig { uri: env::var("SIFT_URI")?, apikey: env::var("SIFT_API_KEY")?, })?; let ingestion_config = get_or_create_ingestion_config(grpc_channel.clone(), ASSET_NAME, CLIENT_KEY).await?; println!( "initialized ingestion config {}", ingestion_config.client_key ); let run = create_run(grpc_channel.clone(), ASSET_NAME).await?; println!("initialized run {}", &run.name); let mut ingestion_service = IngestServiceClient::new(grpc_channel); let data_stream = data_source(); while let Ok((timestamp, velocity)) = data_stream.recv() { let req = IngestWithConfigDataStreamRequest { run_id: run.run_id.clone(), ingestion_config_id: String::from(&ingestion_config.ingestion_config_id), flow: String::from("velocity_reading"), timestamp: Some(Timestamp::from(timestamp)), channel_values: vec![IngestWithConfigDataChannelValue { r#type: Some(Type::Double(velocity)), }], end_stream_on_validation_error: false, ..Default::default() }; ingestion_service .ingest_with_config_data_stream(tokio_stream::once(req)) .await?; println!("ingested a velocity_reading flow"); } println!("done."); Ok(()) } ``` ## Related topics * [Stream your first telemetry data with Python](/documentation/ingest/stream/stream-your-first-telemetry-data-with-python) * [Ingestion config streaming reference](/documentation/reference/stream/ingestion-config-streaming-reference) * [gRPC API reference](/api/reference/protocol-buffers/index) # Influx Line Protocol reference Source: https://docs.siftstack.com/documentation/reference/stream/influx-line-protocol-reference Configuration and examples for streaming data to Sift using an Influx client **Credentials** Before using this method, retrieve your API key and the appropriate Sift URL for your environment. See [Authentication](/documentation/manage/set-up-api-access). Sift accepts data from any Influx client. Use your Sift API key as the Influx authentication token. Pass a small configuration object as a base64-encoded JSON string via the Influx `org` property. ## Ingest URL Point your Influx client to: ``` $SIFT_REST_BASE_URL/api/v0/ingest/influx ``` Influx clients, including Telegraf's `outputs.influxdb_v2` output plugin, automatically append `/api/v2/write` to the configured URL. Use the URL above as is; don't add `/api/v2/write` yourself. ## Configuration object ```json theme={null} { "run": { "name": "your run name", "run_key": "a unique identifier for this run" "tags": ["any", "tags", "associated", "with", "this", "run"] }, "map_bucket_to_tag": "", "omit_bucket": false, "asset_source_tags": ["tag-1", "tag-2"] } ``` ### Configuration fields | Field | Required | Description | | ------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `run` | Optional | Run information. If omitted, data is not grouped into a Run. | | `run.name` | Required if `run` is set | The name of the Run. | | `run.run_key` | Required if `run` is set | A unique key to differentiate runs with the same name. | | `run.tags` | Optional | Tags associated with the Run. Cannot contain spaces. | | `map_bucket_to_tag` | Optional | Renames the Influx bucket tag key. By default, the bucket is added using the key `"bucket"`. | | `omit_bucket` | Optional | If `true`, removes the bucket from the Influx tags. Default is `false`. | | `asset_source_tags` | Required | The Influx tags used to construct the asset name. Tag values are joined with an underscore in the order listed. Use `"bucket"` (or the renamed key) to include the bucket in the asset name. | ## How Influx data maps to Sift * The Influx **measure** maps to the Sift channel **component**. * Influx **tags** that are not used to construct the asset name become part of the channel component. * Each Influx **field** becomes an individual Sift channel. ## Example Given the following Influx line protocol sent to the `CA` bucket: ``` readings,name=truck_0,fleet=West,model=G-2000,device_version=v2.3 latitude=88.177,longitude=168.95208,elevation=420,velocity=22,heading=61 1451692700000000000 ``` And the following configuration object: ```json theme={null} { "run": { "name": "vehicle stats", "key": "372f7888-ad93-4189-b577-1644ca503413" }, "asset_source_tags": ["fleet", "bucket", "name"] } ``` Sift generates the following channels: ``` asset: "West_CA_truck_0" component: "readings(device_version:v2.3)(model:G-2000)" timestamp: "2023-08-09T15:24:15+00:00" ``` | Channel name | Value | | ------------ | --------- | | `latitude` | 88.177 | | `longitude` | 168.95208 | | `elevation` | 420 | | `velocity` | 22 | | `heading` | 61 | The asset name `West_CA_truck_0` is constructed from the `fleet`, `bucket`, and `name` tag values joined with underscores, in the order listed in `asset_source_tags`. The tags `model` and `device_version` are not in `asset_source_tags`, so they become part of the channel component. ## Related topics * [Choose a streaming method](/documentation/ingest/stream/choose-a-streaming-method) * [Organize streamed data into Assets and Runs](/documentation/ingest/stream/organize-streamed-data-into-assets-and-runs) # Ingestion config streaming reference Source: https://docs.siftstack.com/documentation/reference/stream/ingestion-config-streaming-reference Field definitions, protobuf schemas, and examples for ingestion-config-based streaming Ingestion-config-based streaming uses `IngestionConfigService.CreateIngestionConfig` to register the schema of your telemetry, then streams compact structured messages to Sift over gRPC. This approach reduces packet size and improves throughput compared to schemaless methods. ## CreateIngestionConfigRequest ```protobuf theme={null} message CreateIngestionConfigRequest { string asset_name = 1 [(google.api.field_behavior) = REQUIRED]; repeated FlowConfig flows = 2; string organization_id = 3 [(google.api.field_behavior) = OPTIONAL]; string client_key = 4 [(google.api.field_behavior) = OPTIONAL]; } ``` ## FlowConfig A flow is a named group of channels whose values are sent together in one request. ```protobuf theme={null} message FlowConfig { string name = 1 [(google.api.field_behavior) = REQUIRED]; repeated ChannelConfig channels = 2; } ``` ## ChannelConfig ```protobuf theme={null} message ChannelConfig { string name = 1 [(google.api.field_behavior) = REQUIRED]; string component = 2; string unit = 3; string description = 4; sift.common.type.v1.ChannelDataType data_type = 5 [(google.api.field_behavior) = REQUIRED]; repeated sift.common.type.v1.ChannelEnumType enum_types = 6; repeated sift.common.type.v1.ChannelBitFieldElement bit_field_elements = 7; } ``` ### Channel ordering The order of Channels in a `FlowConfig` must be preserved exactly when sending values in an `IngestWithConfigDataStreamRequest`. Sift attributes each value to a Channel by its position in the list. If data is available for some Channels in a flow but not others, send `google.protobuf.Empty` in the position of the missing Channel to maintain correct ordering. **Channel structure mismatch**: If the ingestion client logs `encountered a message that doesn't match any cached flows`, the Channel data sent for that flow doesn't match the flow's Channel structure as registered in `CreateIngestionConfig`. Verify that the Channel names, order, and data types you send match the flow's configured Channels. #### Example Given a flow `reading` with two Channels, a `double` Channel followed by a `string` Channel: ```python theme={null} from sift_stream_bindings import ( ChannelConfigPy, ChannelDataTypePy, FlowConfigPy, ) flow_config = FlowConfigPy( name="reading", channels=[ ChannelConfigPy( name="mainmotor.velocity", unit="km/hr", description="vehicle speed", data_type=ChannelDataTypePy.Double, enum_types=[], bit_field_elements=[], ), ChannelConfigPy( name="log", description="logs", data_type=ChannelDataTypePy.String, enum_types=[], bit_field_elements=[], ), ], ) ``` The corresponding send call must list values in the same order: ```python theme={null} from sift_stream_bindings import ChannelValuePy, FlowPy, TimeValuePy, ValuePy from datetime import datetime, timezone now = datetime.now(timezone.utc) await ingest_client.send( FlowPy( flow_name="reading", timestamp=TimeValuePy.from_timestamp_millis(int(now.timestamp() * 1000)), values=[ # velocity channel (position 0) ChannelValuePy(name="mainmotor.velocity", value=ValuePy.Double(10.0)), # log channel (position 1) ChannelValuePy(name="log", value=ValuePy.String("example log")), ], ) ) ``` ## IngestWithConfigDataStreamRequest ```protobuf theme={null} message IngestWithConfigDataStreamRequest { string ingestion_config_id = 1; string flow = 2; google.protobuf.Timestamp timestamp = 3; repeated IngestWithConfigDataChannelValue channel_values = 4; string run_id = 5; bool end_stream_on_validation_error = 6; string organization_id = 7; } ``` Errors that occur when `end_stream_on_validation_error` is `false` appear in Sift's Data Processing dashboard (`https://app.siftstack.com/manage/data-processing`). **Duplicate timestamps**: If a Channel receives two values at the exact same timestamp, Sift keeps only the most recently written value and discards the earlier one. This deduplication happens at write time, not read time. ## Retrieving an ingestion config by client key ```bash curl theme={null} curl -G -H "Authorization: Bearer $API_TOKEN" -d "filter=client_key=='example_client_key'" $SIFT_REST_URL/api/v1/ingestion-configs ``` ```bash grpcurl theme={null} grpcurl -H "authorization: Bearer $API_TOKEN" -d @ $SIFT_GRPC_URL:$PORT_NUM sift.ingestion_configs.v1.IngestionConfigService/ListIngestionConfigs < ## Updating an ingestion config To add new flows after creation, send a `CreateIngestionConfigFlowRequest` to `IngestionConfigService`. Adding flows and channels is backwards compatible. Modifying or removing existing flows or channels is not. ## Related topics * [Stream telemetry from a running application](/documentation/ingest/stream/stream-telemetry-from-a-running-application) * [Organize streamed data into Assets and Runs](/documentation/ingest/stream/organize-streamed-data-into-assets-and-runs) * [IngestionConfigService API](/api/reference/protocol-buffers/ingestion_configs#ingestionconfigservice) * [IngestService API](/api/reference/protocol-buffers/ingest#ingestservice) # Protobuf ingestion reference Source: https://docs.siftstack.com/documentation/reference/stream/protobuf-ingestion-reference Schema registration, data ingestion, and channel parsing options for protobuf-based streaming The protocol buffers required for protobuf ingestion are not yet available in the public repository. To retrieve them, see [Protocol Buffers](#protocol-buffers) below. Protobuf ingestion enables sending serialized protobuf messages to Sift. Sift derives telemetry channels from the field paths defined in the message structure. The ingestion request accepts a serialized protobuf message (`bytes value`), and the server creates channels based on the message structure. ## How channels are generated from protobuf fields Given the following protobuf message: ```protobuf theme={null} enum VehicleState { Started = 0; Stopping = 1; Stopped = 2; } message Vehicle { float velocity = 3; repeated float direction = 5; VehicleState vehicle_state = 7; PropulsionSubsystem propulsion = 12; map batteries = 13; } message PropulsionSubsystem { float fuel_level } message BatterySystem { float voltage float temp } ``` Sift generates the following channels: * `Vehicle.velocity` * `Vehicle.direction[0]` * `Vehicle.direction[1]` (one channel per array index) * `Vehicle.vehicle_state` * `Vehicle.propulsion.fuel_level` * `Vehicle.batteries[cpu].voltage` (one channel per map key) * `Vehicle.batteries[cpu].temp` * `Vehicle.batteries[propulsion].voltage` * `Vehicle.batteries[propulsion].temp` ## Schema registration ### ProtobufDescriptorService Use `ProtobufDescriptorService.AddProtobufDescriptor` to register a protobuf schema before ingesting messages. **Registration process** * Registration is performed by message type and `namespace`. The `namespace` field enables schema separation between environments. For example, a developer can iterate on protobuf definitions in a separate namespace without affecting live telemetry. * The request takes a `file_descriptor_set` field generated by compiling the protobuf with `protoc`: ```bash theme={null} protoc --include_imports --descriptor_set_out=descriptor.output -I /path/to/protofile ``` **Versioning** Adding multiple `ProtobufDescriptors` with the same message type and `namespace` stores a new version of the descriptor. When a message is ingested, all stored descriptor sets for that message type and namespace are used to generate channel values. The unique set of channels generated is then ingested. **Backward compatibility** New protobuf descriptors must be backward compatible with existing descriptors that share the same `message_type_full_name` and `namespace`. A descriptor is not backward compatible when a field name changes (for example, `velocity` with field number `1` is renamed to `speed`). When a new descriptor is not backward compatible, you will receive an error such as: ``` incompatible protobuf descriptors found. please delete the following protobuf descriptors to successfully add the new descriptor protobuf descriptor ID: 38cd9974-3352-4d5d-afee-05bae1419074, message type full name: vehicle, most recent field name: speed, previous field name: velocity, field number: 1 ``` To resolve this, either make the new descriptor backward compatible by adding a new field and reserving the old one, or delete the old descriptor using the ID in the error message. Use `CheckProtobufDescriptorCompatibility` to check compatibility before registering. **Deletion** `DeleteProtobufDescriptors` removes all descriptors for a given message type and namespace. This is useful for: * Cleaning up test protobuf messages that are no longer in use. * Simplifying ingestion when a new version of the descriptor is fully backward compatible. ## Data ingestion Once the schema is registered, send serialized messages using `IngestService.IngestArbitraryProtobufDataStream`. ## Sift protobuf options To create more descriptive channels, add custom options from `channel_parsing_options.proto` to your protobuf definitions. | Option | Description | | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | | Units and Description | Add units and descriptions to primitive fields. | | Bytes Decoding | Interpret a `bytes`-typed field as another type, such as UTF-8. Enum: `BYTES_DECODING_TYPE_UNSPECIFIED`, `BYTES_DECODING_TYPE_UTF8`. | | Tags | Add context from field values to channel names. Useful when a field path needs additional context to be unique. | | Map Key Display Overrides | Replace the display value of a map key. Useful when keys are not human-readable or have transient values. | | Array Index Overrides | Replace or remove array index display values in channel names. | ### Tagging example A tag source identifies a field whose value becomes a tag on related channels. ```protobuf theme={null} message TestProto { option (sift.protobuf_descriptors.v2.message_is_tag_target) = true; string name = 1; TestChild primary_child = 2 [(sift.protobuf_descriptors.v2.tag_target).allowed_tag_source=DESCENDANT_AND_SIBLING_SOURCES]; repeated TestChild array_of_children = 3; int32 type_id = 4 [(sift.protobuf_descriptors.v2.tag_source).allowed_tag_target=ANCESTOR_TARGETS]; } message TestChild { string child_name = 1 [(sift.protobuf_descriptors.v2.tag_source).allowed_tag_target=ANCESTOR_AND_SIBLING_TARGETS, (sift.protobuf_descriptors.v2.tag_source).tag_name="kid_name"]; map map_int_to_message = 4; } message NestedChild { string sub_child_name = 1 [(sift.protobuf_descriptors.v2.tag_target).allowed_tag_source=SIBLING_SOURCES]; int32 id = 2 [(sift.protobuf_descriptors.v2.tag_source).allowed_tag_target=SIBLING_TARGETS]; } ``` Channels without tags (assuming basic map key and array values): * `TestProto.name` * `TestProto.primary_child.child_name` * `TestProto.primary_child.map_int_to_message[1].sub_child_name` * `TestProto.primary_child.map_int_to_message[1].id` * `TestProto.array_of_children[0].child_name` * `TestProto.array_of_children[0].map_int_to_message[1].sub_child_name` * `TestProto.array_of_children[0].map_int_to_message[1].id` * `TestProto.type_id` Channels with tags applied: * `TestProto(type_id:3).name` * `TestProto(type_id:3).primary_child(kid_name:childname).child_name` * `TestProto(type_id:3).primary_child(kid_name:childname).map_int_to_message[1].sub_child_name(id:35)` * `TestProto(type_id:3).primary_child(kid_name:childname).map_int_to_message[1].id` * `TestProto(type_id:3).array_of_children[0].child_name` * `TestProto(type_id:3).array_of_children[0].map_int_to_message[1].sub_child_name(id:35)` * `TestProto(type_id:3).array_of_children[0].map_int_to_message[1].id` * `TestProto(type_id:3).type_id` Multiple tag values display as `field_name(field_1:value_1)(field_2:value_2)`. ### Map key and array index override example ```protobuf theme={null} enum TestEnum { NONE = 0; SINGLE = 1; DOUBLE = 2; } message TestProto { string name = 1; map map_key_test = 2[(sift.protobuf_descriptors.v2.map_key_override_type)=MAP_KEY_OVERRIDE_TARGET]; map map_key_removal_test = 3[(sift.protobuf_descriptors.v2.map_key_override_type)=MAP_KEY_OVERRIDE_REMOVE_KEY]; map map_key_enum_test = 4[(sift.protobuf_descriptors.v2.map_key_override_type)=MAP_KEY_OVERRIDE_ENUM, (sift.protobuf_descriptors.v2.display_override_enum)="TestEnum"]; repeated ArrayIndexTester array_index_override_test = 5[(sift.protobuf_descriptors.v2.array_index_override_type)=ARRAY_INDEX_OVERRIDE_TARGET]; repeated string array_index_override_remove_index = 6[(sift.protobuf_descriptors.v2.array_index_override_type)=ARRAY_INDEX_OVERRIDE_REMOVE_INDEX]; repeated string array_index_enum_test = 7[(sift.protobuf_descriptors.v2.array_index_override_type)=ARRAY_INDEX_OVERRIDE_ENUM, (sift.protobuf_descriptors.v2.display_override_enum)="TestEnum"]; } message MapKeyTester { string new_key = 1[(sift.protobuf_descriptors.v2.map_key_override_type)=MAP_KEY_OVERRIDE_SOURCE]; float some_value = 2; } message ArrayIndexTester { string new_index = 1[(sift.protobuf_descriptors.v2.array_index_override_type)=ARRAY_INDEX_OVERRIDE_SOURCE]; float other_value = 2; } ``` Channels without overrides (assuming `0` is the only map key): * `TestProto.name` * `TestProto.map_key_test[0].new_key` * `TestProto.map_key_test[0].some_value` * `TestProto.map_key_removal_test[0]` * `TestProto.map_key_enum_test[0]` * `TestProto.array_index_override_test[0].new_index` * `TestProto.array_index_override_test[0].other_value` * `TestProto.array_index_override_remove_index[0]` * `TestProto.array_index_enum_test[0]` Channels with overrides applied (assuming `new_key` value is `my-new-key` and `new_index` value is `my-new-index`): * `TestProto.name` * `TestProto.map_key_test[my-new-key].new_key` * `TestProto.map_key_test[my-new-key].some_value` * `TestProto.map_key_removal_test` * `TestProto.map_key_enum_test[NONE]` * `TestProto.array_index_override_test[my-new-index].new_index` * `TestProto.array_index_override_test[my-new-index].other_value` * `TestProto.array_index_override_remove_index` * `TestProto.array_index_enum_test[NONE]` If multiple override sources apply to the same target, the latest one is used and an error is logged. ## Protocol buffers | Component | Description | API reference | Source | | --------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ | | `ProtobufDescriptorService` | Registers the protobuf schema. | [protobuf\_descriptors](/api/reference/protocol-buffers/protobuf_descriptors) | [GitHub](https://github.com/sift-stack/sift/blob/main/protos/sift/protobuf_descriptors/v2/protobuf_descriptors.proto) | | `IngestService` | Streams serialized protobuf messages. | [ingest#ingestservice](/api/reference/protocol-buffers/ingest#ingestservice) | [GitHub](https://github.com/sift-stack/sift/blob/main/protos/sift/ingest/v1/ingest.proto) | | Channel Parsing | Converts protobuf field paths to channels. | [channel\_parsing\_options](/api/reference/protocol-buffers/channel_parsing_options) | [GitHub](https://github.com/sift-stack/sift/blob/main/protos/sift/protobuf_descriptors/v2/channel_parsing_options.proto) | ## Related topics * [Choose a streaming method](/documentation/ingest/stream/choose-a-streaming-method) * [Stream live telemetry](/documentation/ingest/stream/index) # Schemaless ingestion reference Source: https://docs.siftstack.com/documentation/reference/stream/schemaless-ingestion-reference Field definitions and examples for sending JSON to Sift over REST without pre-registering a schema **Credentials** Before using this method, retrieve your API key and the appropriate Sift URL for your environment. See [Authentication](/documentation/manage/set-up-api-access). Schemaless ingestion lets you send a JSON payload to the `/api/v2/ingest` endpoint without pre-registering an ingestion config. Sift creates the asset and channels automatically if they do not already exist. ## Example request ```bash theme={null} curl -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -X POST "$SIFT_REST_URL/api/v2/ingest" \ --data-raw '{ "asset_name": "test_asset_post_data_0001", "data": [ { "timestamp": "2024-11-06T10:27:20-07:00", "values": [ { "channel": "numeric_channel", "value": 29.18 }, { "channel": "boolean_channel", "value": true }, { "channel": "string_channel", "value": "Example Schemaless String" } ] } ] }' ``` You can also let Sift resolve the run for you by providing `run_config` instead of `run_id`: ```bash theme={null} curl -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -X POST "$SIFT_REST_URL/api/v2/ingest" \ --data-raw '{ "asset_name": "test_asset_post_data_0001", "run_config": { "client_key": "test_run_0001" }, "data": [ { "timestamp": "2024-11-06T10:27:20-07:00", "values": [ { "channel": "numeric_channel", "value": 29.18 } ] } ] }' ``` ## Request fields The name of the asset. If the asset does not exist, it will be created. Required. The `run_id` returned from a previous `CreateRun` call. Optional. Cannot be used together with `run_config`. Resolves a run by client key instead of requiring a `run_id`, so the client does not need to look up or track run IDs itself. Optional. Cannot be used together with `run_id`. If no run with the given `client_key` exists, Sift creates one and uses it. If a run with that `client_key` already exists, Sift resolves its `run_id` and uses it as-is. `run_config` only creates a run when one does not already exist; it never modifies an existing run's name or any other field. An arbitrary user-chosen key that uniquely identifies the run. Must be 3-128 characters, start and end with an alphanumeric character, and contain only letters, numbers, and `_~.-`. Required when `run_config` is provided. The name to give the run if it needs to be created. Only used at creation time and has no effect on an existing run. Defaults to `client_key` if omitted. Optional. The organization ID of the organization that owns the asset. Only required if you are a member of multiple organizations. Optional otherwise. The array of data objects to ingest. The timestamp used for every value in the sibling `values` array. Must be in RFC3339 format. Required. The array of channel values. Every value is assigned the timestamp from the sibling `timestamp` field. The name of the channel. Required. The channel value. Supported types are string, boolean, and number. Required. ## Related topics * [Choose a streaming method](/documentation/ingest/stream/choose-a-streaming-method) * [Organize streamed data into Assets and Runs](/documentation/ingest/stream/organize-streamed-data-into-assets-and-runs) # Streaming error reference Source: https://docs.siftstack.com/documentation/reference/stream/streaming-error-reference The behavior of errors differs between non-streaming and streaming API calls. | Aspect | Non-streaming | Streaming (`IngestData`) | | ------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | | Error scope | Error indicates that specific call failed | Error may mean none of the data points in that request were saved | | Client action | Handle the error appropriately | Retry all data from that request | | Data overwrite | Not applicable | Sift overwrites existing data on retry | | Retransmission risk | Low; discrete calls are self-contained | Higher; client is continuously streaming so it is not guaranteed that an error is related to the last request sent | **Recommendation**: Break data into discrete batches instead of streaming continuously. If a failure occurs, only the latest batch needs to be retried, which improves reliability and reduces the impact of errors on overall data flow. ## Bytes value size limit A single `bytes` (binary) Channel value is limited to **2 MB** (2,097,152 bytes). Sift rejects any larger value during ingestion with an error such as `bytes value is too large: received bytes, limit is 2097152`. This limit applies to each individual data point and is independent of the overall ingestion message size. For binary payloads larger than 2 MB, store the data as a [file attachment](/documentation/review/triage-and-close-out-flagged-issues#attach-a-file-to-an-annotation) rather than streaming it as a `bytes` Channel value. # File formats for import and export Source: https://docs.siftstack.com/documentation/reference/supported-file-formats File formats supported for importing and exporting data in the Sift UI. ## Import file formats The Sift UI supports the following file formats for import: **Import speed**: For large datasets, Parquet imports faster than CSV because Parquet is a more efficient format. For smaller files, the difference is negligible. ## Import file settings ### CSV Settings and requirements for importing CSV files. #### File requirements Your CSV file must meet the following requirements before importing. * **Duplicate timestamps**: A CSV import does not fail if a timestamp repeats within a single column; however, if two rows in the same column share the exact same timestamp, Sift keeps only one of the two values and silently drops the other. Different columns can safely share a timestamp; this only matters within a single column. * **Timestamp column resolution**: If your timestamp column has a coarser resolution than your telemetry rate (for example, one-second resolution for data arriving multiple times per second), Sift keeps only one sample per timestamp, per the duplicate-timestamps behavior above. Use a column with a finer resolution, such as milliseconds, to preserve the full sample rate. * **Blank cells**: A blank cell in a numeric column is skipped and treated as missing data; however a blank cell in a string column creates a real empty string value, which is not treated as missing. This empty string can break Rules that check for an exact string value, and it looks identical to missing data on export. Use an explicit label instead of leaving string cells blank, or use [Parquet](#parquet), which supports an explicit null value for any column type. * **Blank timestamp cells**: A blank cell in the timestamp column fails the import outright, unlike a blank cell in a data column. Filter out rows with a blank timestamp before importing. #### Dialog settings Settings in the **Upload CSV** dialog. ### Parquet Settings and requirements for importing Parquet files. #### File requirements Your Parquet file must meet the following requirements before importing. **Null values**: Parquet supports an explicit null value for any column type, including strings, so you don't need a placeholder label for missing data as you do with CSV. #### Flat Dataset dialog settings Settings in the **Upload Parquet: Flat Dataset** dialog. #### Channel Per Row dialog settings Settings in the **Upload Parquet: Channel Per Row** dialog. #### Complex types modes Applies to Flat Dataset Parquet files. ### TDMS Settings for importing TDMS files. #### Dialog settings Settings in the **Upload TDMS** dialog. #### Channel mapping TDMS imports use the group and Channel hierarchy embedded in the file to derive Channel names. The TDMS dialog does not expose a per-Channel configuration table. Channel-level description properties are imported and appear in the Channel detail panel in the Run view. Embedded enum configurations are also imported and surfaced as enum types on the Channel. To select specific Channels and control how each is imported via the REST API or Python client, use `TdmsDataConfig` entries in the `data` field of `TDMSConfig`. This is recommended when your TDMS file structure does not fit one of the predefined import behaviors. When `data` is empty, Sift imports all Channels and applies the fallback method to any with missing timing information. See [TDMSConfig](/api/reference/protocol-buffers/data_imports#tdmsconfig) in the protocol buffers reference. **Ingested volume**: TDMS and other compact file formats expand when translated into Sift's wire format for ingestion, so the total volume ingested is larger than the source file size on disk. This ingested volume, not the source file size, counts against your ingestion quota. ### HDF5 Settings for importing HDF5 files. #### Schemas The schema determines how Sift interprets the structure of your HDF5 file. #### Dialog settings These settings appear in all three HDF5 upload dialogs. #### Programmatic Channel mapping To map specific datasets to Channels via the REST API or Python client, use `Hdf5DataConfig` entries in the `data` field of `Hdf5Config`. This is recommended when your HDF5 file structure does not fit one of the predefined schemas. When `data` is empty, Sift does not automatically import all datasets; use the predefined schemas instead. See [Hdf5Config](/api/reference/protocol-buffers/data_imports#hdf5config) in the protocol buffers reference. ### ULog Settings for importing PX4 ULog files. #### Dialog settings Settings in the **Upload ULog** dialog. #### Channel naming ULog files are self-describing. Sift detects Channels in the browser before upload and names each one `_.`, for example `sensor_accel_0.x`. Logged status text is imported as `log_messages` Channels. The ULog dialog has no Channel preview or per-Channel configuration. Every Channel is imported automatically. To rename, retype, or select Channels, see **Programmatic Channel selection** below. #### Programmatic Channel selection To select specific Channels via the REST API or Python client, use `UlogDataConfig` entries in the `data` field of `UlogConfig`. When `data` is empty, Sift imports every detected Channel with its default name and type; when `data` is non-empty, only the listed Channels import, and each requires a full Channel config. Use `info_keys` and `param_keys` to import ULog info and parameter values as Run metadata; both require a Run. See [UlogConfig](/api/reference/protocol-buffers/data_imports#ulogconfig) in the protocol buffers reference. The Python client requires the `ulog` extra: `pip install sift-stack-py[ulog]`. ### Timestamp formats Supported timestamp formats for the Time Format setting. **Relative timestamps**: If your timestamp column counts from a device boot time instead of epoch, select a relative format (such as `milliseconds`) and set **Relative Start time (UTC)** to the wall-clock time when the counter was at zero. Selecting an absolute format instead anchors the Run at the Unix epoch (January 1, 1970). ### Channel configuration table #### CSV and Parquet Shown for CSV and Parquet (Flat Dataset). Each non-timestamp column appears as one row. #### HDF5 Each row maps one dataset to a Channel. The columns available are the same across all three HDF5 schemas. ### Data types Supported data types for the Data Type field in the Channel configuration table. **float vs. double**: `float` (32-bit) cannot represent every decimal value exactly, introducing small precision errors (for example, storing `170.9` as `170.89999...`). Use `double` for values where exact decimal precision matters. ## Export file formats The Sift UI supports the following file formats for export: ## Export file settings ### Channel name display Controls how Channel names appear in column headers. ### File splitting Controls how exported data is partitioned across multiple files. ### Channel data grouping Determines how Channels are organized within the exported files. ## Embedded Channel configurations An embedded Channel configuration is a Channel and time configuration that Sift writes directly into an exported CSV or Parquet file. On import, Sift reads this configuration and pre-fills the import configuration automatically, so a file exported from Sift can be re-imported with no manual setup. This is useful for moving data between Assets or environments. You can also construct your own CSV or Parquet files using the shapes below and import them with no additional configuration. ### Enable on export Enable **Embed Channel Configs** when exporting a file. See [Export data to a file](/documentation/export/export-data-from-a-file). ### CSV format Sift inserts a configuration row directly after the header row. Column 0 holds the time configuration JSON; each data column holds a `ChannelConfig` JSON. ### Parquet format Sift writes the configuration to Arrow field metadata. The `sift_time_config` key holds the time configuration JSON on the timestamp field; the `sift_channel_config` key holds the `ChannelConfig` JSON on each data field. ### Channel configuration examples A Channel configuration is a JSON representation of the [ChannelConfig](/api/reference/protocol-buffers/channel_config) protobuf message. ```json theme={null} { "name": "engine.rpm", "units": "rpm", "description": "Engine speed", "data_type": "CHANNEL_DATA_TYPE_DOUBLE", "enum_types": [], "bit_field_elements": [], "metadata": [] } ``` For an enum Channel, `enum_types` maps each integer value to a name: ```json theme={null} { "name": "gearbox.state", "units": "", "description": "", "data_type": "CHANNEL_DATA_TYPE_ENUM", "enum_types": [ { "name": "PARK", "key": 0, "is_signed": false }, { "name": "DRIVE", "key": 1, "is_signed": false } ], "bit_field_elements": [], "metadata": [] } ``` ### Time configuration examples The time configuration is the time format and relative start time as JSON. ```json theme={null} { "time_format": "TIME_FORMAT_ABSOLUTE_RFC3339" } ``` Relative formats set `relative_start_time`, the absolute time that offsets are measured from: ```json theme={null} { "time_format": "TIME_FORMAT_RELATIVE_NANOSECONDS", "relative_start_time": "2026-07-24T00:00:00Z" } ``` ### Import behavior Uploading a file that contains an embedded Channel configuration auto-populates the [Channel configuration table](#channel-configuration-table). Enum and bit field columns expand to reveal their editors if changes are needed. # User-Defined Functions reference Source: https://docs.siftstack.com/documentation/reference/user-defined-functions-settings Settings, options, and behaviors for User-Defined Functions in Sift. User-Defined Functions are reusable CEL expressions that can be called by name inside the expressions of Calculated Channels, Rules, and other User-Defined Functions. They allow teams to define shared logic in one place and reference it across multiple expressions, ensuring consistency and reducing duplication. When a User-Defined Function is updated, the change applies everywhere it is referenced without requiring updates to individual expressions. ## Settings The following table describes each setting available when creating or editing a User-Defined Function. ## Input data types Each input in a User-Defined Function must be assigned one of the following data types. ## Lifecycle actions The following table describes the actions available for managing a User-Defined Function after it has been created. ## Behavior The following table describes known constraints and behaviors to be aware of when working with User-Defined Functions. # Detect and review issues in a Run Source: https://docs.siftstack.com/documentation/review/detect-and-review-issues-in-a-run Generate a Report, review flagged issues, and close them out After completing this topic, you can generate a Report for a Run, investigate the issues it flags, and close them out from start to finish. New to Detect and Review? Read the [Overview](/documentation/review/overview) to understand how Rules, Reports, Annotations, and Campaigns work together before proceeding. ## When to use this workflow Use this workflow when you have a completed Run and want to evaluate it against a set of Rules, examine any flagged issues, and mark them as resolved. This is the core daily loop for anyone doing data review in Sift. ## Before you begin * You have at least one Run in Sift. If you need to import or stream telemetry first, see [Import](/documentation/ingest/data-import/import-data-from-a-file) or [Stream](/documentation/ingest/stream). * At least one Rule exists in your workspace. If no Rules have been created yet, see [Detect deviations automatically using Rules](/documentation/review/detect-deviations-automatically-using-rules). ## Complete the workflow ### Step 1: Generate a Report 1. In **Sift**, select **Runs** in the navigation. 2. In the **Runs** table, click the Run you want to review. 3. Click **Create report**. 4. Click the **Rules** tab. 5. In the **Rules** table, select the Rules you want to evaluate. 6. Click **Evaluate**. Sift evaluates the selected Rules against the Run's telemetry and opens the Report when complete. If your team has already set up a Report Template for this type of Run, use the **Report Template** tab in step 5 to select it. This applies a predefined set of Rules in one click. See [Set up a repeatable review checklist](/documentation/review/set-up-a-repeatable-review-checklist). **Python client**: To generate Reports across many Runs, such as every Run in an Asset's history, use the [Python client](/documentation/reference/stream/client-library-reference) instead of repeating this workflow manually for each Run. If the Report includes a Family Rule, Sift prompts you to resolve the alignment for the Run before evaluation. Map the Run's alignment configurations to the Family's T-0 so the comparison is time-synchronized correctly. See [Detect statistical deviations using Family Rules](/documentation/analyze/families/detect-deviations-from-a-historical-baseline). ### Step 2: Read the Rule summary panel The Report opens with a list of Rules that were evaluated and violated. This means each Rule generated at least one Annotation. Rules that passed without generating any Annotations are not shown by default. Each Rule in the list shows its current state: * **Open**: no Annotations have been reviewed yet. This is the default. * **Failed**: one or more Annotations were marked **Failed**. * **Accepted**: all Annotations were marked **Accepted**. Click any Rule to expand it and see its Annotations and the chart of the channel data that triggered it. For a full definition of each state, see [Annotations reference](/documentation/reference/annotations-reference). ### Step 3: Open an Annotation 1. In the **Rules** section, click the Rule you want to investigate. 2. Click the Annotation listed under that Rule. The Annotation details panel opens on the right. It shows the triggered channel values, the Rule expression that fired, Asset metadata, and a comment thread. ### Step 4: Update the Annotation state In the Annotation details panel, use the status control to change the state from **Open** to either **Failed** or **Accepted**: * Mark **Failed** if the telemetry represents a real problem that must be addressed. * Mark **Accepted** if the finding was reviewed and determined to be valid or not requiring action. State changes are recorded in the activity log. ### Step 5: Leave a comment In the **Enter a comment** box at the bottom of the details panel, type your notes and click **Post**. Comments support rich text and appear alongside state changes in the activity log, giving the full context of the review decision. ### Step 6: Assign the Annotation (optional) If the issue needs follow-up from a specific team member, use **Assigned to** to assign it. Assignment changes are logged alongside comments and state updates. ## Verify the result After reviewing all Annotations in the Report: * Every Rule in the Report should show a state of **Failed** or **Accepted**. None should remain **Open** if the review is complete. * Each Annotation you investigated should have a state, a comment explaining the decision, and an assignee if follow-up is needed. ## Next steps * To set up Rules that detect issues automatically in future Runs, see [Detect deviations automatically using Rules](/documentation/review/detect-deviations-automatically-using-rules). * To create a template so you do not need to pick Rules manually next time, see [Set up a repeatable review checklist](/documentation/review/set-up-a-repeatable-review-checklist). * To triage a large set of Annotations across multiple reviewers, see [Triage and close out flagged issues](/documentation/review/triage-and-close-out-flagged-issues). ## Reference * [Annotations reference](/documentation/reference/annotations-reference) * [Report chart display options](/documentation/reference/report-chart-display-options) # Detect deviations automatically using Rules Source: https://docs.siftstack.com/documentation/review/detect-deviations-automatically-using-rules Automatically flag anomalies in your telemetry without manual inspection. After completing this topic, you can write a CEL-based Rule that flags conditions in your telemetry data. Sift evaluates the Rule against a Run when you generate a Report and flags any deviations automatically. **New to detect and review?** Read the [Overview](/documentation/review/overview) to understand how Rules, Reports, Annotations, and Campaigns work together before proceeding. ## When to use this workflow Use this workflow when you want Sift to flag a specific condition in your telemetry data every time a Run is evaluated. For example, flagging when a channel exceeds a threshold, drops below a minimum, or a log message contains a known error string. Rules are reusable. Once created, a Rule can be applied to any Run and included in Report Templates so your team does not need to reconfigure detection logic from scratch. If your signal's acceptable range varies across tests rather than sitting at a fixed limit, use Family statistics as dynamic thresholds instead. See [Detect statistical deviations using Family Rules](/documentation/analyze/families/detect-deviations-from-a-historical-baseline). ## Before you begin * You have at least one Asset and at least one Channel ingested into Sift. See [Channels](/documentation/reference/channels-reference) and [Assets](/documentation/ingest/stream/organize-streamed-data-into-assets-and-runs). * Optional: You have an existing Run to use for previewing the Rule before saving it. ## Complete the workflow This walkthrough uses a concrete example: flagging when a channel called `motor_temp` exceeds 120 degrees. ### Step 1: Create a new Rule 1. In **Sift**, select **Rules** in the navigation. 2. Click **New Rule**. 3. In **Rule name**, enter a name. For example, `Motor temp over threshold`. 4. Optional: In **Rule description**, enter a description. 5. In **Asset name**, enter or select the Asset that contains the channel you want to monitor. 6. Optional: In **Asset tag name**, enter a tag name to apply this Rule to all Assets with that tag rather than a single Asset. ### Step 2: Select input Channels In the **Input Channels** list, select the channel(s) your Rule expression will reference. For this example, select `motor_temp`. Sift assigns each selected Channel a shorthand variable in selection order: the first Channel becomes `$1`, the second `$2`, and so on. You use these variables in the expression in the next step. You can select both raw telemetry channels and [Calculated Channels](/documentation/transform/create-a-derived-signal). ### Step 3: Write the expression In the **Expression** box, enter a CEL expression that evaluates to `true` when the condition you want to flag is met. Reference input Channels using their assigned shorthand variables. For this example, `motor_temp` was selected first, so it is `$1`: ``` $1 > 120 ``` When this expression evaluates to `true` during a Run, Sift creates an Annotation at that point in time. Keep the expression focused on a single logical condition. Expression resources: * For syntax help, operators, and Sift's built-in functions, see [Expression syntax](/documentation/reference/expression-syntax). * For reusable logic shared across Rules, see [User-Defined Functions](/documentation/transform/reuse-expression-logic). ### Step 4: Preview the Rule against a Run Before saving, preview the Rule against existing telemetry to confirm it behaves as expected. 1. In **Rule preview**, click **Select Run**. 2. In the **Runs** table, select one or more Runs that contain the channel you are monitoring. 3. Click **Preview N Runs**. Sift evaluates the expression against the selected Runs and shows the Annotations that would be generated, without saving them. 4. Review the output to confirm the expression fires when and only when you expect it to. **Preview timeout handling**: Rule preview has a 60-second execution limit and can time out on long Runs with high-rate Channels. If preview times out, save the Rule and evaluate it against the full Run instead of relying on preview to validate it first. ### Step 5: Decide between Rules and Ad Hoc Rules Before publishing, decide whether this Rule should be a standard Rule or an Ad Hoc Rule: * **Rules** are visible by clicking **Rules** in the navigation, can be edited and versioned over time, and are the right choice for ongoing telemetry monitoring. * **Ad Hoc Rules** are created via the API for ad hoc or CI/CD use, are not visible in the UI, and cannot be edited after creation. For most use cases, use a Rule. For CI/CD pipeline integration, see [Rules vs Ad Hoc Rules](/documentation/reference/rule-settings#rules-vs-ad-hoc-rules). ### Step 6: Save and publish the Rule 1. Click **Save**. 2. Optional: In **Version notes**, enter a note describing this version. 3. Click **Publish**. Sift saves the Rule as version 1. Every subsequent edit creates a new immutable version, preserving the full change history. ## Verify the result After publishing: * The Rule appears under **Rules** in the navigation with the Asset and Channels you configured. * You can click the Rule to view its expression, version history, and preview output. * The Rule is now available to select when generating a Report or building a Report Template. ## Next steps * To apply this Rule without manually selecting it each time, add it to a Report Template. See [Set up a repeatable review checklist](/documentation/review/set-up-a-repeatable-review-checklist). * To review a Run using this Rule now, see [Detect and review issues in a Run](/documentation/review/detect-and-review-issues-in-a-run). * To notify an external system the moment this Rule fires during live ingestion, see [Get alerted when a limit is breached](/documentation/manage/get-alerted-when-a-limit-is-breached). * To manage Rule versions or promote an older version to current, see the version history section on the Rule's detail page. * To write a Rule that flags deviations from a historical baseline rather than a fixed value, see [Detect statistical deviations using Family Rules](/documentation/analyze/families/detect-deviations-from-a-historical-baseline). ## Reference * [Expression syntax](/documentation/reference/expression-syntax) # Overview Source: https://docs.siftstack.com/documentation/review/overview Learn how Rules, Reports, Annotations, and Campaigns work together when reviewing a Run After completing this topic, you can understand how Rules, Reports, Annotations, and Campaigns work together and know where to start when reviewing a Run. ## How Review works Review in Sift is organized around a four-object pipeline: **Rule → Report → Annotation → Campaign** Each object has a distinct role. Understanding what each one does and why they are separate is the fastest way to orient yourself before starting a review. ## The review pipeline ### Rules A Rule defines what to look for in your telemetry. You write a logical condition using the [Common Expression Language (CEL)](https://cel.dev). For example, flagging when a channel exceeds a threshold or a log contains a specific string. Rules are reusable across Runs, versioned over time, and shared across your team. Rules are the starting point for anyone setting up automated detection. ### Reports A Report evaluates one or more Rules against a specific Run and collects the results in one place. When you generate a Report, Sift runs each Rule's expression against the Run's telemetry and shows you which Rules passed and which generated issues. Reports are the primary workspace for reviewing a single Run. Most reviewers spend the majority of their time here. ### Annotations When a Rule's condition evaluates to true during a Run, Sift creates an Annotation: a timestamped marker linked to the specific channel values that triggered the Rule. Annotations can also be created manually in Explore. There are two types: * **Phase Annotations**: informational markers for milestones such as "Engine Ignition" or "Max-Q". They have no status and cannot be assigned. * **Data Review Annotations**: issue-tracking entries with a status workflow (`Open`, `Failed`, `Accepted`), an assignee field, and a comment thread. Use these when data needs investigation. Use a Phase Annotation to mark a point of interest for reference, such as a milestone to align on or a boundary between sub-tests in a Run. Use a Data Review Annotation when the finding needs to be tracked to resolution by an assignee. See [Annotations reference](/documentation/reference/annotations-reference) for the full field and behavior differences between the two types. Annotations represent the actual work of review: triaging findings, assigning ownership, and tracking resolution. ### Campaigns A Campaign groups Reports from multiple Runs into a single workspace. Use a Campaign when you need to coordinate a review effort that spans several Runs. For example, all qualification tests for a hardware release. Campaigns are not required for reviewing a single Run. Start with a Campaign only when you are managing a multi-run effort. ## Who uses each object ## Where to start # Set up a repeatable review checklist Source: https://docs.siftstack.com/documentation/review/set-up-a-repeatable-review-checklist Create a standard set of automated checks that applies to every new dataset automatically. After completing this topic, you can create a Report Template that applies a consistent set of Rules to every Run automatically. New to Detect and Review? Read the [Overview](/documentation/review/overview) to understand how Rules, Reports, Annotations, and Campaigns work together before proceeding. ## When to use this workflow Every time you generate a Report without a template, you manually select which Rules to evaluate. For a one-off review this process is fine, but for a recurring test scenario, hardware configuration, or standard review process, it becomes repetitive and error-prone. A **Report Template** solves this by saving a named group of Rules. When you generate a Report, you select the template instead of individual Rules and Sift evaluates all the Rules in the template automatically. Use this workflow when: * You review the same type of Run repeatedly and always apply the same set of Rules. * You want your team to apply a consistent set of checks without remembering which Rules to include. * You are building a standard review process across a program or hardware configuration. ## Before you begin * The Rules you want to include in the template already exist in Sift. See [Detect deviations automatically using Rules](/documentation/review/detect-deviations-automatically-using-rules) if you need to create them first. ## Complete the workflow ### Step 1: Create the template 1. In **Sift**, select **Report Templates** in the navigation. 2. Click **New Report Template**. 3. In **Untitled Report Template**, enter a name that describes the review scenario; for example, `Motor qualification checklist` or `Thermal system review`. 4. Optional: In the **Report Template tags** list, select tags to make the template easier to find. 5. Optional: In **Report Template description**, describe what this template checks and when to use it. ### Step 2: Add Rules to the template 1. Click **Add Rules**. 2. In the **Rules** table, select each Rule you want to include. 3. Click **Confirm selection**. 4. Click **Save new Report Template**. The template is now available to anyone in your workspace when generating a Report. ### Step 3: Apply the template when generating a Report 1. In **Sift**, select **Runs** in the navigation. 2. In the **Runs** table, click the Run you want to review. 3. Click **Create report**. 4. Click the **Report Template** tab. 5. Click the template you want to apply. 6. Click **Evaluate**. Sift evaluates all Rules in the template against the Run and opens the Report. ## When to create a new version of a template Report Templates are not automatically versioned the way Rules are, so keep a consistent naming or tagging convention when your review requirements change. Create a new template (or update the existing one) when: * New Rules have been added to your workspace that belong in the standard checklist. * A hardware revision changes which channels or thresholds are relevant. * A Rule in the template has been archived or replaced with a newer version. When you rerun an existing Report, Sift uses the same Rule versions that were originally evaluated; it does not pick up template changes automatically. To evaluate with updated Rules or a revised template, generate a new Report on the Run instead. ## Verify the result After creating the template: * It appears under **Report Templates** in the navigation. * When generating a Report, the template appears in the **Report Template** tab and applies all its Rules in one step. ## Next steps * To review a Run using your new template, see [Detect and review issues in a Run](/documentation/review/detect-and-review-issues-in-a-run). * To triage the Annotations generated by the Report, see [Triage and close out flagged issues](/documentation/review/triage-and-close-out-flagged-issues). ## Reference * [Annotations reference](/documentation/reference/annotations-reference) * [Report chart display options](/documentation/reference/report-chart-display-options) # Campaigns: track a multi-Run review effort Source: https://docs.siftstack.com/documentation/review/track-a-multi-run-review-campaign Organize Reports from multiple Runs into a Campaign and track overall review progress After completing this topic, you can organize Reports from multiple Runs into a Campaign and track overall review progress in one place. New to Detect and Review? Read the [Overview](/documentation/review/overview) to understand how Rules, Reports, Annotations, and Campaigns work together before proceeding. ## When to use this workflow A **Campaign** groups Reports from multiple Runs into a single workspace. Use a Campaign when: * You are reviewing all Runs from a test program. For example, all qualification tests for a new hardware release. * Multiple reviewers are working in parallel across different Runs and you need a single view of overall progress. * You need to filter and triage Annotations across Runs by assignee, status, Asset, or Rule without opening each Report individually. **Use a single Report instead** when you are reviewing one Run or a small number of Runs where a shared workspace adds no meaningful benefit. ## Before you begin * Two or more Reports already exist for the Runs you want to include. If not, see [Detect and review issues in a Run](/documentation/review/detect-and-review-issues-in-a-run) to generate Reports. * You know the scope of the Campaign (which Runs and Reports are in scope). ## Complete the workflow ### Step 1: Create the Campaign 1. In **Sift**, select **Campaigns** in the navigation. 2. Click **New Campaign**. 3. In the **Campaign name** box, enter a name that describes the review effort, for example, `Thermal system qualification Q2` or `Motor drive endurance test series`. 4. Replace **No description** with a description of the Campaign scope. 5. Click **Add report**. 6. In the **Reports** table, click the Reports you want to include. 7. Click **Confirm selection**. 8. Click **Save**. ### Step 2: Add Reports from additional Runs As new Runs complete and Reports are generated, add them to the Campaign: 1. In **Campaigns**, click the Campaign. 2. Click **Edit reports**. 3. In the **Reports** table, click the Reports you want to add. 4. Click **Confirm selection**. **Adding Multiple Runs**: Adding Reports to a Campaign requires manually selecting each Report in the UI. To add a large number of Runs, such as an Asset's entire Run history, use the [Python client](https://sift-stack.github.io/sift/python/latest/) to add Runs to the Campaign instead of adding them one by one. ### Step 3: Track progress using Annotation filters Inside the Campaign, use the **View Annotations** option (in the left navigation) to see all Annotations across every included Report in one place. Apply filters to monitor progress: * Filter by **Status** to see how many Annotations remain Open across the entire Campaign. * Filter by **Assignee** to see each reviewer's outstanding work. * Filter by **Run**, **Asset**, or **Rule** to isolate a specific area of concern. The **View/edit Campaign** section provides a summary of Annotation status that can be grouped by Run, Report, Assignee, or Rule, giving a high-level view of where the review stands. ### Step 4: Decide when the Campaign is done A Campaign has no automatic completion state. Use the following criteria to determine when the effort is complete: * All Annotations in the Campaign have a state of **Failed** or **Accepted**, and none remain **Open**. * Any Annotations marked **Failed** have been assigned and have a documented next action. * Stakeholders have been notified or reports shared as needed. Once complete, the Campaign serves as a historical record of the review effort. ## Verify the result After completing the Campaign setup: * The Campaign appears under **Campaigns** in the navigation. * The **View Annotations** section shows all Annotations from all included Reports in a single filterable list. * Team members can navigate to the Campaign to see their assigned issues without opening individual Reports. ## Next steps * To triage specific Annotations within the Campaign, see [Triage and close out flagged issues](/documentation/review/triage-and-close-out-flagged-issues). * To share a Report with stakeholders outside the Campaign, open the Report, hover over its title, and click **Share** to copy a link. * To tag the Campaign with a requirement, program, or hardware identifier so it is easy to find later, see [Organize resources with Metadata](/documentation/manage/organize-and-filter-resources-with-metadata). ## Reference * [Annotations reference](/documentation/reference/annotations-reference) # Triage and close out flagged issues Source: https://docs.siftstack.com/documentation/review/triage-and-close-out-flagged-issues Work through a Report's Annotations: assign, update, and resolve issues to drive a review to completion After completing this topic, you can work through a Report's Annotations systematically: assigning, updating, and closing out every flagged issue. New to Detect and Review? Read the [Overview](/documentation/review/overview) to understand how Rules, Reports, Annotations, and Campaigns work together before proceeding. ## When to use this workflow Use this workflow when a Report has been generated and you need to work through its Annotations systematically: 1. Filtering by status or owner 2. Distributing work across teammates 3. Adding evidence 4. Driving every issue to a final state This is the day-to-day workflow for reviewers. It picks up where [Detect and review issues in a Run](/documentation/review/detect-and-review-issues-in-a-run) leaves off and covers the full range of tools available for managing Annotations at scale. ## Before you begin * At least one Report exists for the Run you are reviewing. If not, see [Detect and review issues in a Run](/documentation/review/detect-and-review-issues-in-a-run). * You have the team members' names available if you plan to assign Annotations. ## Complete the workflow ### Filter Annotations by state or assignee **Annotations** in the navigation provides a workspace-level view of all Annotations across all Runs. Use the filters at the top to narrow down to the issues you want to work on: * Filter by **Status** (Open, Failed, Accepted) to see only unreviewed or in-progress items. * Filter by **Assignee** to see only the issues assigned to a specific team member. * Filter by **Asset**, **Run**, or **Rule** to focus on a specific scope. You can also access Annotations directly within a Report by clicking a Rule and then an Annotation in the Rules section. ### Assign issues to teammates 1. In **Sift**, select **Annotations** in the navigation. 2. In the **Annotations** table, click the Annotation you want to assign. 3. In the **Assigned to** selector, choose a team member. Assignment changes are recorded in the activity log alongside comments and state transitions, so the full history of ownership is preserved. ### Add a comment 1. In the Annotation details panel, locate the comment thread. 2. Type your notes in the comment box. Comments support rich text. 3. Click **Post**. Use comments to document your reasoning when making a review decision, flag follow-up actions, or provide context for the next reviewer. ### Attach a file to an Annotation To attach a file directly to an Annotation: 1. In **Sift**, select **Annotations** in the navigation. 2. In the **Annotations** table, click the Annotation you want to attach a file to. 3. In the **File attachments** section, click **Attach**. 4. Upload the file. To attach a file to a specific comment on an Annotation: 1. In the comment, click **Attach**. 2. Upload the file. 3. Click **Post**. For supported file types and size limits, see [Annotations reference](/documentation/reference/annotations-reference). ### Download an attached file To download a file attached to an Annotation: 1. In the **File attachments** section, expand it. 2. Hover over the file you want to download. 3. Click **Download**. To download a file attached to a comment, locate the comment, hover over the file, and click **Download**. ### Move an Annotation through its states In the Annotation details panel, use the status control to transition the Annotation: * **Open** → **Failed**: the telemetry represents a real problem that must be addressed. * **Open** → **Accepted**: the finding was reviewed and determined to be valid or not requiring action. * **Failed** or **Accepted** → **Open**: reopen the Annotation if new information changes the assessment. For the full list of valid state transitions, see [Annotations reference](/documentation/reference/annotations-reference). Phase Annotations do not support state changes or assignment. Only Data Review Annotations have the status workflow described above. ### Archive a resolved Annotation Once an Annotation is fully resolved and no longer needs to appear in the active view, archive it: 1. In the Annotation details panel, scroll to the bottom and click **Archive**. 2. Confirm in the dialog. Archived Annotations are soft-deleted. They no longer appear in the tree or on charts but can be restored. To restore an archived Annotation, locate it in the archived view and click **Restore**. ## Verify the result A triage pass is complete when: * Every Data Review Annotation in the scope of your review has a state of **Failed** or **Accepted**, and none remain **Open**. * Issues requiring follow-up have an assignee and a comment explaining the next action. * Supporting evidence (screenshots, logs, or other files) is attached to Annotations where context is needed. ## Next steps * To track progress across a multi-Run effort, see [Track a multi-run review campaign](/documentation/review/track-a-multi-run-review-campaign). * To share a Report with a stakeholder, open the Report, hover over its title, and click **Share** to copy a link to your clipboard. ## Reference * [Annotations reference](/documentation/reference/annotations-reference) * [Annotations reference](/documentation/reference/annotations-reference) # Calculated Channels: create a derived signal Source: https://docs.siftstack.com/documentation/transform/create-a-derived-signal Use a Calculated Channel to compute a new derived signal without modifying the original telemetry data. After completing this workflow, you can create a Calculated Channel that derives a new signal from one or more existing Channels, without modifying the original telemetry. ## Before you begin * You are familiar with how Sift organizes data into Assets, Channels, and Runs. * If not, see [Understand Assets, Channels, and Runs](/documentation/get-started/data-model). * You have at least one Asset with ingested telemetry data and know which Channels you want to use as inputs. * You have at least one Run that includes the input Channels you plan to use, so you can verify the derived signal after creating it. ## How Calculated Channels work A derived signal is created using a Calculated Channel. A Calculated Channel is a new signal computed from one or more existing Channels using a [CEL expression](/documentation/reference/expression-syntax). Sift evaluates the expression against each incoming data point and stores the result as a separate Channel, leaving the original telemetry intact. Each input Channel is assigned a shorthand variable (`$1`, `$2`, and so on) based on the order you select them. You use these variables to write the expression. Input Channels can be raw Channels or other Calculated Channels (up to 10 levels of nesting are supported). For example, say you want to compute the power draw of a system from its voltage and current Channels. Instead of exporting the raw data and computing it manually, you select both Channels and write `$1 * $2` as the expression. ## Create a Calculated Channel 1. Select **Calculated Channels** in the navigation. 2. Click **New Calculated Channel**. 3. In the **Calculated Channel name** box, enter a name for the derived signal. 4. In the **Asset name** list, select the Asset associated with your input Channels. 5. In the **Input Channels** list, select one or more Channels to use in the expression. * To use raw telemetry, select one or more existing Channels. * To build on a previously derived signal, select an existing Calculated Channel. * You can mix raw Channels and Calculated Channels as inputs. 6. In the **Query** box, write a [CEL expression](/documentation/reference/expression-syntax) using the assigned input variables. * To call shared logic, reference a User-Defined Function directly in the expression. 7. Optional: In the **Units** box, enter the unit of measurement for the derived signal. 8. Optional: In the **Calculated Channel(s) Preview** section, click **Select Run** to select a Run, then review the plot to confirm the derived signal behaves as expected against the input Channels. 9. Click **Save**. **Asset scope**: A Calculated Channel is scoped to the Asset you select in step 4. It does not appear when you open a different Asset in Explore. To apply the same Calculated Channel to multiple Assets, set the **Asset tag name** field. Any Asset tagged with that value can use the channel. For all available settings, see [Calculated Channel reference](/documentation/reference/calculated-channel-settings). ## Verify the created Calculated Channel You can confirm the Calculated Channel is working correctly in two ways: * **During creation**: In the **Calculated Channel(s) Preview** section, select a Run to confirm the expression produces the expected values against the input Channels. * **After saving**: Select **Runs** in the navigation, then search for and select the Run that contains the input Channels used in the expression, click **Explore**, then in the **Calculated Channels** tab, click your new Calculated Channel to plot it alongside the source Channels. If the values look unexpected, return to the Calculated Channel, review the expression, and use the preview to validate changes before saving. ## Next steps * [Reuse expression logic](/documentation/transform/reuse-expression-logic) * Once you have created a derived signal, learn how to define expression logic once as a User-Defined Function and reference it across multiple Calculated Channels and Rules to avoid rewriting the same expression each time. ## Reference * [Calculated Channels reference](/documentation/reference/calculated-channel-settings) * [CEL expression](/documentation/reference/expression-syntax) # Reference files in expressions Source: https://docs.siftstack.com/documentation/transform/reference-files-in-expressions Use file data from Assets and Runs in Rule and Calculated Channel expressions instead of hardcoding values. After completing this workflow, you can reference external file data directly in Rule and Calculated Channel expressions to compare telemetry against thresholds, apply calibration values, or use configuration data that changes between Runs without hardcoding values in your expressions. ## Before you begin * You have an Asset or a Run with at least one file attached in a [supported format](/documentation/reference/expression-syntax#supported-file-formats). * You have an existing Rule or Calculated Channel to edit, or you are ready to create a new one. ## How file references work Rule and Calculated Channel expressions can access data from files attached to an Asset or a Run using two functions: `assetFile()` and `runFile()`. **Live Rules**: Rules that reference files can't be used in live Rule evaluation. File functions are not supported in live Rule evaluation. * `assetFile("filename.format")` reads a file attached to the Asset the Rule or Calculated Channel is configured for. * The file is verified when the expression is created or edited. * Use this for data that stays the same across Runs, such as hardware limits, calibration offsets, or hardware specifications. * `runFile("filename.format")` reads a file attached to the Run being evaluated. * The file is resolved at evaluation time, when a Rule is evaluated against a Run, or when a Calculated Channel is evaluated against a Run. * Use this for data that changes between Runs, such as test parameters, environmental conditions, or per-session acceptance criteria. Once a file is loaded, you access specific values using [bracket notation](/documentation/reference/expression-syntax#bracket-notation). The syntax depends on the file format. For supported formats and syntax, see [File functions](/documentation/reference/expression-syntax#file-functions). ## Reference a file in an expression 1. Attach a file to the Asset or the Run you want the expression to reference. 2. Create a new Rule or Calculated Channel, or open an existing one to edit. 3. In the **Expression** editor, use `assetFile("filename")` or `runFile("filename")` to reference the file by name. 4. Use [bracket notation](/documentation/reference/expression-syntax#bracket-notation) to index into the specific value. 5. Verify the expression: * **Rules**: Preview the Rule against an existing Run to confirm the expression resolves correctly. * **Calculated Channels**: Preview the Calculated Channel against a Run to confirm the expression resolves correctly. ## Examples ### Rules ### Calculated Channels ## Reference * [CEL expression](/documentation/reference/expression-syntax#file-functions) # Reuse expression logic Source: https://docs.siftstack.com/documentation/transform/reuse-expression-logic Define expression logic once and reference it across multiple Calculated Channels, Rules, and User-Defined Functions. After completing this workflow, you can define a CEL expression once as a User-Defined Function and call it by name in Calculated Channels, Rules, and other User-Defined Functions, keeping logic consistent and reducing duplication across your workspace. ## Before you begin * You are familiar with how Sift organizes data into Assets, Channels, and Runs. * If not, see [Understand Assets, Channels, and Runs](/documentation/get-started/data-model). * You know the CEL expression logic you want to reuse. If you need help writing expressions, see [Expression syntax](/documentation/reference/expression-syntax). ## How reusable expression logic works A **User-Defined Function** is a reusable CEL expression that can be called by name inside the expressions of Calculated Channels, Rules, and other User-Defined Functions. It does not produce a signal on its own. It acts as a building block that encapsulates a piece of logic, such as a threshold calculation or a normalization formula, that you want to apply consistently across multiple places in your workspace. Each input in a User-Defined Function is assigned a shorthand variable (`$1`, `$2`, and so on) based on the order you define them. You use these variables to write the expression, just as you would in a Calculated Channel. ### Example For example, say you want to convert temperature readings from Celsius to Fahrenheit across multiple assets. Instead of writing `($1 * 9/5) + 32` in every Calculated Channel and Rule separately, you define it once as a User-Defined Function called `celsius_to_fahrenheit` with the expression `($1 * 9/5) + 32`. You can then reference it in Calculated Channels, Rules, and other User-Defined Functions: * In a Calculated Channel: `celsius_to_fahrenheit($1)` * In a Rule: `celsius_to_fahrenheit($1) > 200` If the conversion logic changes, you update the function once and the change applies everywhere it is referenced automatically. ## Create a User-Defined Function 1. Select **User-Defined Functions** in the navigation. 2. Click **New Function**. 3. In the **User-defined function name** box, enter a name for the function. For naming requirements, see [User-Defined Functions settings](/documentation/reference/user-defined-functions-settings#settings). 4. Optional: In the **Description** box, enter a description of what the function does. 5. In the **Input Channels** box, select a data type for the first input (`$1`). * To add more inputs, click **Add input Channel** and select a data type for each additional input. 6. In the **Expression** box, write the CEL expression using the defined input variables. For supported syntax, see [Expression syntax](/documentation/reference/expression-syntax). 7. Optional: In the **Preview** section, click **Select Run** to select a Run, then review the plot to confirm the function produces the expected values against the input Channels. 8. Click **Save**. ## Verify the function You can confirm the User-Defined Function is working correctly in two ways: * **During creation**: In the **Preview** section, select a Run, and review the output to confirm the expression produces the expected values before saving. * **After saving**: The function appears in the **User-Defined Functions** section of the Expression Syntax panel. Call it in a Rule, Calculated Channel, or other User-Defined Function to confirm it behaves as expected. ## Reference * [User-Defined Functions reference](/documentation/reference/user-defined-functions-settings) * [CEL expression](/documentation/reference/expression-syntax) # Troubleshooting Source: https://docs.siftstack.com/documentation/troubleshoot/troubleshooting Learn how to fix common configuration issues. This guide covers the common issues users encounter and provides steps to resolve them quickly. If your issue is not listed here, please contact support with details about your browser, operating system, and the steps taken before the issue occurred. To contact support in Sift, click your profile, and then click **Customer Support**. If the issue occured during a Run, include a sharelink of the Run or Asset/Run ID. ## Plot and visualization issues These are the most common types of issues and are typically related to rendering, zooming, or large datasets. ### Zoom does not work (X or XY zoom is unresponsive) This usually happens when: * The dataset being plotted is very large * The plot has not fully finished loading * The browser is temporarily overloaded * FFT or high-resolution rendering is enabled In some cases, the browser tab might appear frozen while processing data. 1. Wait 10–15 seconds to allow the plot to fully load. 2. Refresh the browser tab. 3. Reduce the time range being plotted. 4. Plot fewer Channels at once. 5. Disable FFT (if enabled). 6. Close other heavy browser tabs and try again. If the issue persists, provide support with: * Browser and OS version * Time range plotted * Number of Channels * Whether FFT was enabled ### Plot freezes or browser tab locks up This typically occurs when: * Plotting a very large time range * Viewing high-sample-rate data * Plotting many Channels simultaneously * Rendering FFT on large datasets * The browser might become temporarily unresponsive while processing. 1. Refresh the page. 2. Reduce the plotted time range. 3. Plot fewer Channels. 4. Disable FFT (if enabled). 5. Try a different browser to confirm whether the issue is browser-specific. If reproducible, share the exact plot configuration or link with support. ### Error after removing a Channel from a plot This might occur when: * A removed Channel is still referenced in the plot state * A shared link contains outdated Channel references * A rendering state mismatch occurs after dynamic updates 1. Refresh the page. 2. Re-add the Channel and then remove it again. 3. Recreate the plot from scratch. 4. If using a shared link, regenerate the link. 5. Clear browser cache and retry. If the error continues, provide a share link and reproduction steps to support. ### Annotations obscure plotted data Annotations might render above data layers, which can cause labels or markers to visually block parts of the timeseries. 1. Toggle annotation visibility off (if available). 2. Zoom in to reduce visual overlap. 3. Reduce annotation density where possible. 4. Capture a screenshot and report if this significantly affects usability. ### Metadata box values appear swapped or incorrect In rare cases, the UI rendering state might temporarily mismatch labels and values, particularly after zooming or rapid interactions. 1. Zoom slightly in or out. 2. Refresh the page. 3. Reopen the plot in a new tab. 4. Clear browser cache if the issue persists. If the issue consistently reproduces, report with: * Screenshot * Browser version * Plot configuration ## Channel and layout issues ### Long Channel names overlap or break layout Very long Channel names might exceed the available UI width, leading to: * Overlapping text * Truncated names * Misaligned layout elements 1. Resize your browser window. 2. Hover over truncated names to view the full Channel name (if tooltip is available). 3. Rename Channels to shorter aliases (if appropriate). 4. Report cases where the layout breaks completely. See Asset [naming conventions](/documentation/ingest/stream/organize-streamed-data-into-assets-and-runs#naming-conventions) and [Channel naming restrictions](/documentation/reference/channels-reference#naming-restrictions). ### Channel labels appear duplicated or formatted incorrectly This might occur when: * Channel metadata includes overlapping naming attributes * Asset or Run information is appended multiple times * A UI formatting issue is triggered 1. Refresh the page. 2. Remove and re-add the Channel. 3. Verify the Channel's metadata configuration. 4. If persistent, provide the Channel name and Asset details to support. ## Rule configuration issues ### Rule shows "Error" instead of "Failure" This occurs when the Rule itself is misconfigured, rather than the data violating a correctly written Rule. * Rules are written as CEL expressions. When Rule logic is discussed in this section, it is referring to CEL expression validity. See [Rules overview](/documentation/review/detect-deviations-automatically-using-rules). * See [live Rule limitations](/documentation/review/detect-deviations-automatically-using-rules#live-rules-limitations). There are two distinct outcomes when a Rule Runs: * **Failure**: The Rule logic is valid, but the data violates it. * **Error**: The Rule configuration is invalid or cannot execute properly. An error state is typically caused by: * Invalid or incomplete Rule logic * Incorrect threshold expressions * Referencing fields or Channels that do not exist * Invalid arguments in Rule conditions * Unsupported comparison types In these cases, the system cannot properly evaluate the Rule, so it enters an error state rather than reporting a failure. 1. Review the Rule configuration carefully. 2. Confirm all referenced Channels or fields exist and are spelled correctly. 3. Verify thresholds and comparison operators are valid. 4. Ensure the Rule logic matches the intended data type (numeric vs boolean vs string). 5. Save the Rule and test it on a small, known dataset. 6. If the error persists, copy the error message and provide: * Rule configuration * Asset or Run used ### Rule never evaluates or shows no results If a Rule appears to never run, or produces no failures or results, it is often due to configuration scope rather than a system issue. Common causes include: * The Rule is attached to the wrong Asset * No data exists in the selected time range * The Rule is scoped to Runs that do not contain matching data * Filters or conditions prevent the Rule from executing * The Rule is not enabled or not associated with an active evaluation context ### Rule errors when a Run is missing a referenced Channel Sift requires every Channel referenced in a Rule to exist on the Run being evaluated. If a Channel only reports data under certain conditions, such as a mode that is not always active, Runs where that Channel never reports have no Channel to reference, and the Rule cannot evaluate. Split the logic into two Rules: 1. A general Rule that does not reference the conditional Channel, so it evaluates on every Run. 2. A Rule that adds the conditional Channel as an extra input, so it only evaluates on Runs where that Channel is present. Run both Rules via a Report. On Runs where the conditional Channel is absent, the second Rule shows a per-Rule error; this is expected, not a failure of the first Rule. Preview the two Rules one at a time. Previewing both together against a Run that is missing the conditional Channel can hide the other Rule's result in the Preview panel. ## Python client (sift-stack-py) issues ### Import fails in a PyInstaller windowed EXE When `sift-stack-py` is imported inside a PyInstaller windowed build (compiled with `--noconsole` or `--windowed`), the process has no attached console, so Python sets `sys.stdout` and `sys.stderr` to `None`. An internal dependency used by `sift-stack-py` attempts to write to these streams on import and raises an error before any Sift code runs. This affects all `sift-stack-py` versions prior to the fix released in response to this issue. **Recommended**: Upgrade to the latest version of `sift-stack-py`, which handles `None` streams internally. ```bash theme={null} pip install --upgrade sift-stack-py ``` **Workaround for older versions**: Add the following snippet at the top of your entry-point module, before any `sift-stack-py` import: ```python theme={null} import sys import os if sys.stdout is None: sys.stdout = open(os.devnull, "w", encoding="utf-8") if sys.stderr is None: sys.stderr = open(os.devnull, "w", encoding="utf-8") ``` This redirects the missing streams to `/dev/null` so the dependency initializes without error. Place this code before any `from sift...` or `import sift` statements. ## Streaming issues ### Ingestion fails with a bytes value size limit error A single `bytes` (binary) Channel value is limited to **2 MB** (2,097,152 bytes). Sift rejects any larger value during ingestion with an error such as `bytes value is too large: received bytes, limit is 2097152`. This limit applies to each individual data point and is independent of the overall ingestion message size. For binary payloads larger than 2 MB, store the data as a [file attachment](/documentation/review/triage-and-close-out-flagged-issues#attach-a-file-to-an-annotation) rather than streaming it as a `bytes` Channel value. ## File import issues ### Import fails with gRPC RESOURCE\_EXHAUSTED error This error occurs when importing a Parquet file that contains a large number of Channels. The import configuration Sift generates for the file can exceed the 10 MiB gRPC message size limit even when the data file itself is smaller than that threshold. ``` StatusCode.RESOURCE_EXHAUSTED grpc: received message larger than max (X vs. 10485760) ``` The error is thrown by the [CreateDataImportFromUpload](/api-reference/dataimportservice/createdataimportfromupload#createdataimportfromupload) endpoint. The configuration size scales with the number of Channels defined in the file, not the volume of data. Split the Parquet file into multiple smaller files, each containing a subset of the Channels, then import each file separately targeting the same Asset and Run. For example, if your file contains 500 channels: 1. Create **File A** with channels 1–250. 2. Create **File B** with channels 251–500. 3. Import File A and File B as separate imports, both mapped to the same Asset and Run. Sift is working on increasing the gRPC message size limit to accommodate files with large channel counts in a future release. # Learning path Source: https://docs.siftstack.com/learning-path/overview Begin your Sift journey and grow your confidence with step-by-step tutorials Get your data into Sift from files or a live stream. Explore different methods for ingesting historical data. Explore the different streaming options available for live data ingestion. Use Explore's Panels to spot patterns and dig into the details that matter. Discover Sift's tools to explore, navigate, inspect, and compare your telemetry. Detect issues automatically and get notified the moment they happen. Use Sift's Rules and Reports features to automatically detect anomalies and summarize insights. Enable real-time notifications by connecting Rule triggers to external systems using Webhooks. Derive and reuse logic across your telemetry. Use Calculated Channels to generate new signals and metrics from your existing telemetry. Centralize reusable transformation logic using User-Defined Functions. Organize your workspace so resources stay easy to find. Use Metadata to add structured context to your workspace resources for faster searching and better organization. # Conclusion Source: https://docs.siftstack.com/learning-path/tutorial-1/conclusion In this tutorial, you learned how to import and visualize historical data in Sift. You explored how Sift organizes time-series telemetry and developed an understanding of how historical data can be ingested. You then imported a CSV file using one of these approaches and visualized the data in Sift's Explore, learning how to explore and analyze historical measurements once they are available in Sift. # Tutorial 1: Import and visualize historical data in Sift Source: https://docs.siftstack.com/learning-path/tutorial-1/overview Explore different methods for ingesting historical data By the end of this tutorial, you'll be able to import historical data into Sift using the method that best fits your workflow and visualize that data to uncover trends and insights. We'll walk through the different import options Sift offers, then put them into practice by ingesting a dataset and exploring it with Sift's visualization tools. ## Objectives * Understand the different options Sift offers to import historical data into Sift * Learn how to visualize imported data ## Prerequisites * Download the following CSV file: [tutorial-1-data.csv](https://drive.google.com/uc?export=download\&id=1fLNXV0bM1AbO9Z9T4DJUH2YJo1Qz6SNE) # Step 1: Understand how Sift organizes telemetry data Source: https://docs.siftstack.com/learning-path/tutorial-1/step-1 ## Overview Before covering the different import options, let's review how Sift organizes time-series data. ## Assets, Channels, and Runs Sift uses three core building blocks: [Assets](../../documentation/ingest/stream/organize-streamed-data-into-assets-and-runs), [Channels](../../documentation/reference/channels-reference), and [Runs](../../documentation/reference/runs-reference). These building blocks help structure telemetry data, making it easier to explore, analyze, and reuse it across different experiments or observation periods. * **Assets**: These represent physical or virtual systems that generate data. * **Channels**: These represent individual time-series signals recorded from an Asset. * **Runs**: These represent time windows or observation sessions during which data is collected from one or more Channels. # Step 2: Discover methods to import historical data Source: https://docs.siftstack.com/learning-path/tutorial-1/step-2 ## Overview Before learning how to visualize historical data in Sift, this step introduces the different methods available for **importing historical (backfill) datasets**. Historical data refers to data that was collected in the past and uploaded to Sift after the fact, rather than streamed in real time. ## Options Sift supports multiple methods for importing historical data. Each method is suited to different workflows and supports specific file formats, as shown below: # Step 3: Understand how to visualize imported historical data Source: https://docs.siftstack.com/learning-path/tutorial-1/step-3 ## Overview Now that you better understand the different options Sift offers for importing historical data, in this step, let's import a CSV file and explore how to visualize it in Sift. The CSV contains data from a low Earth orbit (LEO) satellite. ## Import a CSV Let's import a CSV: 1. Select **Runs** in the navigation, then select **Import data**. 2. Upload the [tutorial-1-data.csv](https://drive.google.com/uc?export=download\&id=1fLNXV0bM1AbO9Z9T4DJUH2YJo1Qz6SNE) file. 3. Click the **Asset** toggle to the **New** position. 4. In the **Asset name** box, enter: ``` fl_tutorial_1_asset ``` 5. In the **tutorial-1-data.csv** box, edit the Run name with the following: ``` fl_tutorial_1_run ``` 6. Replace `fl` (in `fl_tutorial_1_asset` and `fl_tutorial_1_run`) with your initials (first and last name). This helps avoid naming conflicts if others are also completing the tutorial on the same Sift instance. 7. Click **Upload**. 8. Click **Close** ## Visualize data Now that we have imported the dataset, let's visualize the imported CSV. 1. In the **Run name or description** box, enter the name of the created Run (for example, **fl\_tutorial\_1\_run**) and select it. 2. Click **Explore**. Explore is Sift's workspace for working through high-rate timeseries data to uncover root causes, spot trends, and get answers faster. It gives engineers one place to visualize telemetry across Panels, perform calculations, compare telemetry across tests, and share a snapshot view with colleagues. Engineers go from “something happened” to “here’s what happened and here’s the proof” without exporting telemetry or switching tools. 3. In the **Channels** tab, click the following Channels: 1. Under the **motor\_b** section, click the following Channels: * **current** * **encoder** # Conclusion Source: https://docs.siftstack.com/learning-path/tutorial-2/conclusion In this tutorial, you reviewed the different ways to stream live data into Sift and learned how to reason about which streaming method best fits a given use case. You also ran a live streaming example using one of these methods and observed the incoming data in the Sift interface. By visualizing live telemetry as it was sent to Sift, you learned how to explore and monitor real-time data, preparing you to confidently work with live streams and apply these concepts to your own systems. # Tutorial 2: Stream and visualize live data in Sift Source: https://docs.siftstack.com/learning-path/tutorial-2/overview Explore the different streaming options available for live data ingestion By the end of this tutorial, you will be able to stream live data into Sift using the approach that best fits your use case and begin exploring that data in real time. We will walk through the different streaming options Sift provides, then put one into practice so you can see your data flowing into Sift and ready for analysis. ## Objectives * Understand the different options Sift offers to live-stream data into Sift * Learn how to observe live-streamed data in Sift ## Prerequisites * Basic understanding of Python * A Sift API key and your Sift gRPC and REST base URLs * This tutorial describes how to create an API key and obtain your URLs. # Step 1: Discuss options to live stream data Source: https://docs.siftstack.com/learning-path/tutorial-2/step-1 ## Overview Before we learn how to observe live-streamed data in Sift, let's explore in this step the different options Sift offers for live-streaming data into Sift. ## Options Sift supports multiple options for ingesting data as it is generated in real time. The following table summarizes each live-streaming method, including the type of data it accepts and the scenarios in which it is typically used. # Step 2: Understand how to observe live-streamed data Source: https://docs.siftstack.com/learning-path/tutorial-2/step-2 ## Overview Now that you understand the different methods available for live-streaming data into Sift, let's explore how to observe live-streamed data in Sift. For this tutorial, we'll simulate live-streaming by running a Python script that sends robotic vehicle telemetry (such as velocity and internal temperature) to Sift via the `sift_client`. This data is generated every 0.5 seconds and is used to demonstrate how streaming data can be observed in Sift. ## Live-streamed data Follow the steps below to live-stream robotic vehicle telemetry data. 1. Clone the Sift repository and navigate to the ingestion tutorial directory: ```bash theme={null} git clone https://github.com/sift-stack/sift.git cd sift/python/examples/ingestion-tutorial ``` 2. Create and activate a Python virtual environment, then install the required packages: ```bash theme={null} python3.11 -m venv venv source venv/bin/activate pip install -r requirements.txt ``` 3. Create a `.env` file and provide your Sift instance URLs and API key: ```bash theme={null} touch .env ``` ```bash theme={null} SIFT_API_KEY=your_api_key_here SIFT_GRPC_URL=https://your-grpc-url SIFT_REST_URL=https://your-rest-url ``` To obtain your instance URLs and an API key: 1. In **Sift**, click your profile icon, which shows the first initial of your account name. 2. Select **Manage**. 3. In the **Manage** navigation menu, click **API Keys**. 4. Click **+ Create API Key**. 5. In the **Name** box, enter a name for the API key. 6. In the **User** list, select your email to link to the API key. 7. Click **Create**. 8. Click **Copy**. 9. Click **Close**. 10. In the **REST API URL** field, click **Copy**. 11. In the **gRPC API URL** field, click **Copy**. 4. Run the following command to live-stream data to Sift: ```bash theme={null} python stream.py ``` * Check the terminal for the generated Run name * For example, **robot\_vehicle\_…\_run** * You will use this Run name to access the live-streamed data shortly ## Observe live-streamed data Now that data is being streamed to Sift, let's see how we can observe that data live. 1. Open the **Run** that the data is being streamed to. In particular, open the Run using **Explore**. 2. In **Explore**, click **Live**. 3. In the **Channels** tab, select the following Channels: 1. **temperature** 2. **velocity** 4. Before concluding this step, stop the streaming with the following command: ```bash theme={null} Ctrl+C ``` # Conclusion Source: https://docs.siftstack.com/learning-path/tutorial-3/conclusion In this tutorial, you explored how Sift visualizes and analyzes telemetry using Panels in Explore. You learned what different Panel types are designed for, how they help render and interpret time-series data, and how to arrange Panels into a multi-panel layout. Together, these steps showed how Panels in Explore helps you uncover patterns, relationships, and cross-subsystem effects in telemetry data. # Tutorial 3: Visualize and analyze data with interactive telemetry charts Source: https://docs.siftstack.com/learning-path/tutorial-3/overview Discover Sift's tools to explore, navigate, inspect, and compare your telemetry By the end of this tutorial, you'll be able to use Explore's Panels to visualize, navigate, and interpret your telemetry data in Sift. We'll walk through each Panel type available in Explore and show you how to use them to render your data in meaningful ways, spot patterns, and dig into the details that matter most. # Step 1: Learn about Panels Source: https://docs.siftstack.com/learning-path/tutorial-3/step-1 ## Overview So far, you have been using only one of the many Panels available in Explore. In this step, let's explore all available Panels to analyze an array of different telemetry data types. ## Panels For a full list of available panels and what each one does, see [Panels](/documentation/reference/explore-settings#panels). # Step 2: Create a multi-Panel layout Source: https://docs.siftstack.com/learning-path/tutorial-3/step-2 ## Overview Now that you understand the available Panels in Explore, in this step you will learn how to arrange them in a multi-Panel layout. ## Multi-Panel layout Let's create a multi-Panel layout. 1. Using **Explore**, open the Run created in [Tutorial 1](../tutorial-1/overview). 2. Create a few **Timeseries** Panels: * Panel 1: 1. Click the **Timeseries** tile. 2. In the **Channels** tab, under the **camera\_1** section, click **current**. * Panel 2: 1. Click **Plus**, then select **Timeseries**. 2. In the **Channels** tab, under the **camera\_2** section, click **temperature**. * Panel 3: 1. Click **Plus**, then select **Timeseries**. 2. In the **Channels** tab, under the **motor\_a** section, click **encoder**. 3. Create a **Table** Panel: 1. Click **Plus**, then select **Table**. 2. In the **Channels** tab, under the **motor\_b** section, click the following Channels: * **current** * **encoder** * **temperature** 4. Create a **multi-Panel** layout: 1. Click and hold the **Table 1** tab, then drag it to the bottom of the screen. Release when that area highlights. 2. Click and hold the **Timeseries 3** tab, then drag it to the right side of the top Panel area. Release when the area highlights. 3. Click and hold the **Timeseries 2** tab, then drag it to the right of the **Timeseries 2** Panel. Release when the right-side highlight appears. # Conclusion Source: https://docs.siftstack.com/learning-path/tutorial-4/conclusion In this tutorial, you learned what Rules are, how to create one using a CEL-based expression, and how to preview it against an existing Run to verify it behaves as expected. You also generated a Report to review the Rule's evaluations, inspect the Annotations it triggered, and assess system behavior during a Run. # Tutorial 4: Automatically detect and summarize issues in telemetry data Source: https://docs.siftstack.com/learning-path/tutorial-4/overview Use Sift's Rules and Reports features to automatically detect anomalies and summarize insights By the end of this tutorial, you'll be able to create logic-based expressions in Sift that automatically evaluate your telemetry and surface conditions of interest, helping you detect anomalies as they happen. We'll walk through how to build these expressions, apply them to your data, and use them to flag the moments that need your attention. # Step 1: Create a Rule Source: https://docs.siftstack.com/learning-path/tutorial-4/step-1 ## Overview Let's discuss and create a Rule in Sift, which enables you to create logical conditions to evaluate your telemetry. ## What are Rules Rules in Sift are logical conditions, defined using the Common Expression Language (CEL), that evaluate telemetry across one or more Channels from an Asset to detect behaviors, anomalies, and threshold breaches in live and historical data. * When a Rule evaluates to true, it can create Annotations, send notifications, or be assigned to a user for follow-up * Rules support versioning and previewing against existing Run data ## Preview and create a Rule To better understand Rules, let's create one that captures a specific behavior in a Channel from the low Earth orbit satellite (LEO) we explored in [Tutorial 1](../tutorial-1/overview). Specifically, we'll create a Rule for the temperature Channel in the **camera\_1** subsystem that triggers an Annotation when the temperature exceeds **30** degrees Celsius. This ensures future datasets are automatically checked for similar anomalies and flagged for review. 1. Select **Rules** in the navigation. 2. Click **New Rule**. 3. In the **Rule name** box, enter the following: ``` fl_tutorial_4_rule ``` 4. Replace `fl` (in `fl_tutorial_4_rule`) with your own initials. 5. In the **Asset name**, select the Asset created in [Tutorial 1](../tutorial-1/overview). * **For example**: fl\_tutorial\_1\_asset 6. In the **Input Channels** list, select the following Channel: * **camera\_1.temperature** 7. In the **Enter an expression** box, enter: ``` $1 > 30 ``` * **Channel references**: Selected Channels are referenced in the expression using `$1`, `$2`, `$3`, and so on, in the order they appear in the **Input Channels** list. In this case, `$1` refers to **camera\_1.temperature**. * **Functions**: Expressions support a variety of built-in function types for different kinds of calculations. To browse all available functions, observe the **Expression Syntax** section. 8. Click **Select Run(s) to preview**. 9. Click the Run created in [Tutorial 1](../tutorial-1/overview). * **For example**: fl\_tutorial\_1\_run 10. Click **Preview 1 Runs**. 11. Click **Save**. # Step 2: Generate a Report Source: https://docs.siftstack.com/learning-path/tutorial-4/step-2 ## Overview Now that you've created a Rule, let's explore Reports, a built-in way to review how your Rules evaluated telemetry during a Run, inspect the Annotations they generated, and assess the overall health and behavior of your system. ## What are Reports Reports provide a consolidated view of how the Rules configured for an Asset evaluated telemetry during a Run, including the [Annotations](../../documentation/reference/annotations-reference) they generated and their current status. Annotations are markers that Sift creates when a Rule condition is met. They highlight an exact moment in your telemetry data. ## Create a Report Let's create a Report for our created Run. 1. Select **Runs** in the navigation, then in the **Run name or description** box, enter the name of the Run created in [Tutorial 1](../tutorial-1/overview). * **For example**: fl\_tutorial\_1\_run 2. In the **Runs** table, click your Run. 3. Click **Create Report**. 4. Click the **Rules** tab. 5. In the **Rules** table, click the Rule you created. * **For example**: fl\_tutorial\_4\_rule 6. Click **Evaluate**. ## Open generated Report After a few seconds, the report should be ready. Let's open it. 1. Select **Reports** in the navigation. 2. In the **Report name** box, enter the name of the Run created in [Tutorial 1](../tutorial-1/overview). * **For example**: fl\_tutorial\_1\_run 3. In the **Reports** table, click the name of the created Run. In a Report, you can assign trigger Annotations to specific users, or you can comment on them to enable further discussion with others. For example: 1. In the **Rules** section, click **14:21:36**. 2. Optional: In the **Assigned to** list, assign a user to the generated Annotation. 3. Optional: In the **Comments and logs** box, enter a comment for the generated Annotation. # Conclusion Source: https://docs.siftstack.com/learning-path/tutorial-5/conclusion In this tutorial, you learned what Webhooks are, how to create one from the Manage page, and how to connect one to a Rule. By attaching the Webhook to the Rule from the previous tutorial, Sift is now prepared to notify external systems whenever the Rule enters a violated or resolved state during live data evaluation. # Tutorial 5: Trigger real-time alerts from live data events Source: https://docs.siftstack.com/learning-path/tutorial-5/overview Enable real-time notifications by connecting Rule triggers to external systems using Webhooks. By the end of this tutorial, you'll be able to set up Webhooks in Sift that deliver real-time notifications the moment a Rule detects an important condition in your telemetry. You'll create a Webhook, configure its payload, and connect it to the Rule you built in Tutorial 4 so that it's ready to fire notifications as soon as live telemetry is evaluated. ## Prerequisites * Only users with an Admin or Editor role can create Webhooks. You must be granted access to Webhooks before continuing. If you do not have the required permissions, contact your administrator. * Basic understanding of webhooks # Step 1: Understand Webhooks Source: https://docs.siftstack.com/learning-path/tutorial-5/step-1 ## Overview Webhooks allow Sift to notify external systems the moment a Rule transitions into a violated or resolved state during live evaluation, actively pushing information instead of requiring another system to poll for changes. Each Webhook sends an outbound request to a destination system with a customizable payload that describes what happened and can include context from the Rule that triggered the event. Note that Webhooks only fire during live Rule evaluations and do not run when Rules are evaluated against historical data. # Step 2: Create a Webhook Source: https://docs.siftstack.com/learning-path/tutorial-5/step-2 ## Overview In this step, you will create a Webhook that will later be connected to the Rule you created in the previous tutorial. Webhooks in Sift are created and managed from the **Manage** page. ## Create a Webhook Let's create a Webhook. 1. Click your profile menu. 2. Select **Manage**, then open **Webhooks** from the navigation menu. 3. Click **Create webhook**. 4. In the **Webhook name** box, enter the following: ``` fl_tutorial_5_webhook ``` 5. Replace `fl` (in `fl_tutorial_5_webhook`) with your initials (first and last name). 6. In **Trigger event type**, select **Rule violation**. 7. In **Destination URL**, enter the the following: ``` https://example.com/webhook ``` * This is an example destination URL. It is provided so you can continue through the Webhook configuration flow. In a real environment, this would be replaced with the URL of a system that can accept Webhooks. 8. Click **Next**. On this page, you can specify custom HTTP headers and send a test notification to the selected destination URL. You can also define the payload that will be sent when the Webhook fires, either by using [built-in variables](../../documentation/manage/get-alerted-when-a-limit-is-breached#built-in-variables) or by starting from one of the available templates. For the purposes of this tutorial, you will use one of the templates to send a payload to Slack when the Rule created in the previous tutorial enters a violated or resolved state during live data evaluation. 9. In the **Payload config** list, select **Slack**. The Slack template you selected uses built-in variables associated with the [Rule Violation](../../documentation/manage/get-alerted-when-a-limit-is-breached#rule-violation) trigger event type. These variables allow the payload to include useful context about the Rule and where it was evaluated. * `{{.RuleName}}` and `{{.RuleVersion}}` identify the Rule that triggered the Webhook * `{{.Status}}` indicates whether the Rule entered a violated or resolved state * `{{.AssetName}}` and `{{.RunId}}` provide context about the Asset and Run involved in the evaluation Sift replaces these placeholders automatically when sending the Webhook. 10. Click **Save**. # Step 3: Connect the Webhook to the Rule Source: https://docs.siftstack.com/learning-path/tutorial-5/step-3 ## Overview Now that the Webhook is created, let's connect it to the Rule from the previous tutorial. Once connected, the Webhook will fire whenever the Rule enters a violated or resolved state during live data evaluation. This means that if live data is streamed to the Channels of the Asset associated with the Rule and the Rule's condition is met, Sift will automatically send a notification to the configured destination URL. ## Connect Webhook Let's connect the created Webhook. 1. Select **Rules** in the navigation. 2. Search for the Rule created in the previous tutorial and click **Edit**. 3. Click the **Enable live Rule evaluation** checkbox. 4. In the **Webhooks** section, click **+ Configure Webhook**. 5. Enter the Webhook name, select the created Webhook, and click **Select**. 6. Click **Save**, then click **Publish**. # Conclusion Source: https://docs.siftstack.com/learning-path/tutorial-6/conclusion In this tutorial, you learned how Calculated Channels work, created a derived signal using a CEL expression, and plotted it alongside the original Channel to compare the results. These concepts provide a foundation for building more advanced analyses and deeper insight into system behavior through transformed and derived data. # Tutorial 6: Create new signals from original data Source: https://docs.siftstack.com/learning-path/tutorial-6/overview Use Calculated Channels to generate new signals and metrics from your existing telemetry By the end of this tutorial, you'll be able to use Calculated Channels in Sift to derive new signals from your existing telemetry, all without modifying the underlying source data. We'll walk through how to create and configure Calculated Channels so you can transform and enrich your data to suit your analysis needs. # Step 1: Understand Calculated Channels Source: https://docs.siftstack.com/learning-path/tutorial-6/step-1 ## Overview **Calculated Channels** in Sift let you define custom metrics and derive new signals from existing Channels using [CEL](https://cel.dev) expressions, without modifying the original data. Sift supports two types of transformations: * **Stateless**: Processes each data point independently, ideal for real-time computations like unit conversions or threshold checks. For example, converting a temperature Channel from Celsius to Fahrenheit. * **Stateful**: Retains context over time, enabling trend analysis and detection of gradual changes. For example, computing a rolling average over a defined time window. # Step 2: Create a Calculated Channel Source: https://docs.siftstack.com/learning-path/tutorial-6/step-2 ## Overview To better understand how Calculated Channels work, let's create one using the temperature Channel from the LEO dataset in Tutorial 1. Specifically, we will create a Calculated Channel that converts the **camera\_1.temperature** Channel from Celsius to Fahrenheit. ## Create a Calculated Channel 1. Select **Calculated Channels** in the navigation. 2. Click **New Calculated Channel**. 3. In the **Calculated Channel name** box, enter the following: ``` fl_tutorial_6_calculated_channel ``` 4. Replace `fl` (in `fl_tutorial_6_calculated_channel`) with your initials. 5. In the **Asset** list, select the Asset you created in Tutorial 1. 6. In the **Input Channels** list, select the following Channel: * **camera\_1.temperature** 7. In the **Query (expression)** box, enter the following: ``` ($1 * 9/5) + 32 ``` Expressions define how a Calculated Channel derives its values from input data. They can reference input Channels (for example, `$1`), other Calculated Channels, constants, operators, and built-in functions. Before saving, you can preview the output to verify the expression behaves as expected. 8. Click the **Select Run(s) to preview** tile. 9. In the **Runs** table, click the name of the Run created in Tutorial 1. 10. Click **Preview 1 Runs**. 11. Click **Save**. # Step 3: Plot a Calculated Channel Source: https://docs.siftstack.com/learning-path/tutorial-6/step-3 ## Overview Calculated Channels can be plotted alongside the original Channels of an Asset in Explore. ## Plot Calculated Channel 1. Select **Runs** in the navigation, then open the Run created in Tutorial 1 in **Explore**. 2. In **Explore**, in the **Channels** tab, click the following Channel in the **camera\_1** section: * **temperature** 3. Click the **Calculated Channels** tab, then click the name of the created Calculated Channel. * **For example**: fl\_tutorial\_6\_calculated\_channel # Conclusion Source: https://docs.siftstack.com/learning-path/tutorial-7/conclusion ## Summary In this tutorial, you learned how User-Defined Functions work, created one using the **camera\_1.temperature** Channel from the LEO dataset to convert temperature from Celsius to Fahrenheit, and saw how it can be reused across Rules and Calculated Channels. # Tutorial 7: Build reusable logic for consistent data transformation Source: https://docs.siftstack.com/learning-path/tutorial-7/overview Centralize reusable transformation logic using User-Defined Functions By the end of this tutorial, you'll be able to create User-Defined Functions in Sift that encapsulate custom logic you can reuse across Calculated Channels and Rules. We'll walk through how to define these functions and apply them so you can keep your logic consistent, reduce duplication, and streamline your workflows. # Step 1: Understand User-Defined Functions Source: https://docs.siftstack.com/learning-path/tutorial-7/step-1 ## Overview User-Defined Functions let you define custom logic once as a named expression and reuse it wherever expressions are supported in Sift, including Calculated Channels, Rules, and other User-Defined Functions. They behave like built-in functions, can use built-in functions within their definitions, support optional inputs and constant values, and are version-controlled so logic can evolve safely. # Step 2: Create a User-Defined Function Source: https://docs.siftstack.com/learning-path/tutorial-7/step-2 ## Overview To better understand User-Defined Functions, let's create one using the LEO dataset from Tutorial 1. This function will use the **camera\_1.temperature** Channel to convert the temperature from Celsius to Fahrenheit, allowing it to be reused consistently across a Calculated Channel and a Rule. ## Create a User-Defined Function 1. Select **User-Defined Functions** in the navigation. 2. Click **New Function**. 3. In the **User-Defined Function name** box, enter: ``` fl_tutorial_7_user_defined_function ``` * User-Defined Function names must meet the following requirements: * No spaces * Must be 1 to 253 characters long * Must start with a letter * Use only letters, numbers, and underscores 4. Replace `fl` (in `fl_tutorial_7_user_defined_function`) with your initials. 5. In the **Enter an expression** box, enter the following: ``` ($1 * 9/5) + 32 ``` * In this expression, `$1` is a placeholder that refers to the first input Channel assigned to the function, in this case **camera\_1.temperature**. Each input Channel can be assigned a data type, including * **Number**, * **String**, * **Boolean**, or * their constant equivalents (**Constant Number**, **Constant String**, **Constant Boolean**). * Constant types use fixed values defined in the function that do not change between evaluations, while non-constant types receive their values from Channels at the time the function is called. * For this function, `$1` is defined as a **Number** since **camera\_1.temperature** is a numeric Channel. * When a function needs to operate on more than one Channel, you can add additional inputs and reference them as `$2`, `$3`, and so on. * For example, if you wanted to calculate the temperature difference between two cameras in the LEO dataset, you could add **camera\_1.temperature** as `$1` and **camera\_2.temperature** as `$2`, and write the expression as * `$1 - $2`. 6. In the **Preview** section, click **Select Run to preview**. 7. In the **Run name or description** box, enter the name of the created Run in Tutorial 1. 8. Click **Next**. 9. In the **Channel name** list, select **camera\_1.temperature**. 10. Click **Preview**. 11. Click **Save**. # Step 3: Apply User-Defined Functions Source: https://docs.siftstack.com/learning-path/tutorial-7/step-3 ## Overview Once created, a User-Defined Function becomes available anywhere expressions are used in Sift, including Rules, Calculated Channels, and other User-Defined Functions. In the expression editor, User-Defined Functions appear in the **Expression Syntax** panel under the **User-Defined Functions** section. ## Using User-Defined Functions in expressions When defining an expression, you can reference a User-Defined Function just like a built-in function. In the examples below, `$1` refers to **camera\_1.temperature**. For example, in a Calculated Channel: ``` fl_tutorial_7_user_defined_function($1) ``` Or in a Rule, as part of a logical condition: ``` fl_tutorial_7_user_defined_function($1) > 86 ``` Because User-Defined Functions are defined once and reused across expressions, updating the function's logic applies the change centrally without requiring updates everywhere it is used. # Conclusion Source: https://docs.siftstack.com/learning-path/tutorial-8/conclusion ## Summary In this tutorial, you learned how to create a Metadata key, assign a predefined value to it, attach it to the LEO dataset Run from Tutorial 1, and use it to search for that Run. The same approach can be applied to other resources such as Assets, Rules, Calculated Channels, Reports, and User-Defined Functions, helping your workspace remain organized and easy to navigate as it grows. # Tutorial 8: Tag and search workspace resources with Metadata Source: https://docs.siftstack.com/learning-path/tutorial-8/overview Use Metadata to add structured context to your workspace resources for faster searching and better organization. By the end of this tutorial, you'll be able to use Metadata in Sift to improve discoverability and organization across your workspace. Using the Run from the LEO dataset in Tutorial 1, you'll create a Metadata key, attach it to the Run, and then use it to quickly search for and locate that Run. # Step 1: Understand Metadata Source: https://docs.siftstack.com/learning-path/tutorial-8/step-1 ## Overview Metadata in Sift consists of organization-defined key-value pairs with fixed data types, including string, number, and boolean, that provide a structured way to describe and organize workspace resources beyond their names. Each key is defined once and applied consistently across the workspace, making resources easier to search and filter. ## Where Metadata can be applied Metadata can be attached to Runs, Assets, Annotations, Rules, Reports, Campaigns, Calculated Channels, and User-Defined Functions, allowing the same organizational structure to be shared across different types of resources. # Step 2: Create a Metadata key Source: https://docs.siftstack.com/learning-path/tutorial-8/step-2 ## Overview In this step, you will create a string Metadata key called `fl_data_source` to help identify the Run from the LEO dataset in Tutorial 1. The key name represents the attribute you want to track, in this case the source of the data. You will also assign a predefined value to the key, which will appear as a selectable option when the key is applied to a resource. ## Create a Metadata key 1. Click your profile icon, which shows the first initial of your account name. 2. Select **Manage**, then open **Metadata** from the navigation menu. 3. Click **+ Create Metadata key**. 4. In the **Name** box, enter: ``` fl_data_source ``` 5. Replace `fl` (in `fl_data_source`) with your initials. 6. Click **Create**. * Next, let's assign a predefined value to the key. 7. In the **Metadata key name** box, enter the name of the created Metadata key. 8. In the **Metadata keys** table, click **Options**, then select **View values**. 9. In the **Enter string value** box, enter the following: ``` fl_option_1_data_source ``` 10. Replace `fl` (in `fl_option_1_data_source`) with your initials. 11. Click **Add value**. 12. Click **Close**. # Step 3: Use Metadata to improve discoverability Source: https://docs.siftstack.com/learning-path/tutorial-8/step-3 ## Overview In this step, you will attach the Metadata key you created to the Run from the LEO dataset in Tutorial 1 and use it to search for and locate that Run. ## Attach Metadata key to a Run 1. Select **Runs** in the navigation, then in the **Run name or description** box, enter the Run name from Tutorial 1. * **For example**: fl\_tutorial\_1\_run 2. In the **Runs** table, click the name of the Run. * **For example**: fl\_data\_source 3. Click **Edit**. 4. Click **Add Metadata**. 5. In the **Select or create** list, select the name of the created Metadata key. 6. In the **Enter or select value** list, select the created option for the Metadata. * **For example**: fl\_option\_1\_data\_source 7. Click **Save Changes**. ## Search for a Run using its attached Metadata key 1. Select **Runs** in the navigation, then click **Metadata**. 2. In the **Select key** list, select the name of the Metadata key created in the previous step. 3. In the **Enter or select value** list, select the created option for the created Metadata. Each resource in Sift's navigation, such as **Runs**, **Assets**, **Annotations**, **Rules**, **Reports**, and **Calculated Channels**, includes a Metadata filter that lets you search for resources using attached Metadata, making it easier to locate specific data as your workspace grows. # April 2026 Source: https://docs.siftstack.com/release-notes/2026/april-2026 New ways to investigate telemetry and build on your calculated metrics April 2026 ships a rebuilt Explore workspace, the ability to use Calculated Channels in Rule logic, and support for referencing Calculated Channels within other Calculated Channel calculations. ## New Investigate telemetry in one workspace Skip the back-and-forth between tools when investigating telemetry. Open the new [Explore](/documentation/reference/explore-settings) as Sift's default workspace, shaped around your everyday workflows. Investigate telemetry in one workspace ## New Alert on every Calculated Channel Catch problems in every metric your team calculates. Feed any [Calculated Channel](/documentation/reference/calculated-channel-settings) into a Rule and reuse the same alert logic you already rely on. ## New Build calculations on top of calculations Cut duplicate work and keep every dependent metric in sync. Drop any existing [Calculated Channel](/documentation/transform/create-a-derived-signal#create-a-derived-signal) into a new calculation, and updates flow through automatically. # Import flight logs, reuse investigations, and shape your Channel tree Source: https://docs.siftstack.com/release-notes/2026/august-2026 Release notes · August 2026 Bring PX4 flight logs into Sift in their native format, reopen any Explore session exactly as you left it, and control how Channel names build your Channel tree. ## Event Sift Edge demo: capture telemetry offline at the test stand Sift Edge is now available. Join Benjamin Nguyen, Lead Engineer for Sift Edge, and Zach Plunkett, Solutions Architect, for a 30-minute demo on Wednesday, August 19 at 10 AM PT. See Sift Edge in action: capture telemetry locally and view it live at the test stand, even without an internet connection. You'll also see how Sift Edge uploads selected runs to Sift once you reconnect. Expect roughly 20 minutes of demo and 10 minutes of Q\&A. * Watch a [two-minute preview](https://youtu.be/rSRJR0R9wnY) of what to expect * [Register here](https://www.siftstack.com/edge-webinar#register-webinar) to save your spot ## New Import PX4 flight logs (ULog) straight into Sift Bring [ULog files](/documentation/ingest/data-import/import-data-from-a-file) into Sift through the UI, CLI, Python client, or API (REST and gRPC). * Analyze PX4 flight telemetry in its native format, ready the moment it lands * Correlate vehicle parameters and system messages alongside your Channels * Line up flight events with the rest of your Run on one timeline, anchored to a start time you supply or GPS time when none is set ULog import ## New Reopen any investigation exactly as you left it Save the full state of an Explore session, then reopen it to pick up where you left off. [Saved Explorations](/documentation/reference/explore-settings#saved-explorations) are now generally available to every team. * Capture Panels, layout, data sources, Channels, time range, and compare settings in one saved state * Start a recurring investigation from a known baseline * Share a Saved Exploration as a template for onboarding or operation-specific analysis Saved Explorations ## Beta Shape your Channel tree with two new delimiter settings Control how Channel names resolve into the Channel tree with two new settings that build on the existing [Channel Name Delimiter](/documentation/reference/naming-rules#channel-name-structure) setting. * Add a Channel name prefix delimiter to split off folder-style paths, such as the slash in `telemetry/motor.rpm` * Set Channel leaf keywords to trim repetitive trailing segments that recur across many Channel names * Keep source Channel names as they are and shape the Channel tree in Sift Delimiter settings # February 2026 Source: https://docs.siftstack.com/release-notes/2026/february-2026 Scalable data analysis in context This release makes Sift more capable and easier to use by helping engineers analyze telemetry in context. Teams can now calculate statistics over any time window, align signals with images and video, build reusable derived metrics, and navigate dense multi-axis data with greater precision, moving faster from raw signals to confident insight. ## Beta Measure your data over any time range Select any section of your timeline in Explore v2 (Beta), and the Metrics Panel gives you the numbers: minimum, maximum, mean, and more. No need to export anything or switch tools. * Pick a time range, and see stats for every signal in that window. * Turn on "Follow selections" to update the numbers as you move through your data. * Choose which stats you care about, lock a range for repeated checks, and export to CSV when you need a report. Calculate statistics for any data window ## New Play back video, images, and audio synced to your telemetry Explore critical moments with precise time alignment in Explore v2 (Beta) using the File Viewer Panel to correlate images, video, and audio with your telemetry data. Review media inline and anchor it directly to your data, enabling seamless movement between signal behavior and real world context within a single, unified view. * Set a start timestamp for accurate time correlation, * inspect images with built in zoom and pan, and * stay oriented during playback with hover mirroring across Panels. Align data with critical visual moments
Video footage courtesy of SpaceX. Used here for educational and analytical purposes to demonstrate Sift's telemetry tools.
## Beta Reuse existing calculations to build new metrics, without starting from scratch Build new calculations using Calculated Channels you've already created. Change one, and every metric that depends on it updates automatically. * Edit one building block, and every metric that uses it stays up to date. * Built-in validation catches circular references and missing inputs before they cause any issues. * Dependency previews show you which calculations feed into which, so you can trace the logic at a glance. Reference existing calculations to build complex metrics ## New Sort, group, and focus signals across up to eight axes Organize busy charts and find the data that matters with new legend controls and focused tooltips in Explore v2 (Beta). Drag signals between axes, group them by type or source, and hover to highlight what you care about. Add up to eight independent axes to the Timeseries Panel and cut through visual noise. Tooltips now show only the nearest data point. * Drag signals between axes to compare them side by side. * Group legend items by data source, type, or units. * Hover over a trace to highlight it and dim everything else. Navigate dense data with greater precision # January 2026 Source: https://docs.siftstack.com/release-notes/2026/january-2026 Collaborative analysis and data portability This month, we are launching new features that give you more precise control over your telemetry. These capabilities make it easier to share targeted visual reviews and export data for external analysis. ## New Launch targeted analyses via dynamic URLs Create custom dynamic URLs that open Explore v2 (Beta) with pre-specified data. This capability allows you to: * Define exact session parameters, including the specific Run or Asset, Channels, Panel type, and precise start/end times. * Automate complex visual setups using dynamic links that eliminate the need for manual configuration. * Ensure team members land on the exact telemetry and timeframe required for their review immediately upon clicking. Parameterized URLs
[Documentation](../../documentation/reference/explore-settings)
## New Easily recreate and share visual analyses Standardize your analysis using Panel Configurations, which have moved from Beta to General Availability (GA). This feature allows you to capture and reuse the complete visualization setup of an individual Panel to: * Save specific Channel selections, axis mappings, and styling preferences for instant recall. * Share these configurations across your organization to provide the granular control needed to recreate complex visual analyses. * Standardize your analysis workflow by instantly reproducing saved visual setups. Panel Configurations
[Documentation](../../documentation/reference/explore-settings)
## New Export data to Parquet Move your telemetry beyond Sift for custom analysis by exporting Runs or specific Channels into a Parquet format. This ensures your data remains portable and allows you to: * Transfer high-volume telemetry into any tool that supports the Parquet standard, such as pandas, DuckDB, or Polars. * Preserve native data types and precision, eliminating the need for manual cleanup. * Empower your team to perform complex analysis in your preferred data stack. Export Run to Parquet
[Documentation](../../documentation/reference/supported-file-formats)
# New Panels, faster rendering, and Saved Explorations Source: https://docs.siftstack.com/release-notes/2026/july-2026 Release notes · July 2026 This release ships Sift CLI v0.2.0 with HDF5 and TDMS imports, Parquet export, and built-in documentation. It also adds two new Panel types and performance improvements to the Timeseries Panel in Explore. Explorations can now be saved and reused across Runs, Assets, and Families. ## New Move telemetry in and out of Sift from the terminal Bring more telemetry into Sift straight from the terminal with the Sift [CLI](/documentation/cli/sift-cli) v0.2.0. * Import HDF5 and TDMS files in their native format, with a preview before upload * Export to Parquet for downstream analysis alongside existing export formats * Confirm authentication and connectivity before starting a long-running upload * Access reference documentation directly in the terminal ## Beta Pick up any investigation where you left off and reuse it across the team Save the full state of an Explore session as a [Saved Exploration](/documentation/reference/explore-settings#saved-explorations), including Panels, layout, selected Runs, Assets, Families, Channels, time range, and compare settings. Open a Saved Exploration to continue an in-progress investigation or to start a recurring one from a known baseline. * Reuse the same exploration across Runs, Assets, and Families for consistent analysis * Share explorations with teammates as templates for onboarding or operation-specific analysis Saved Explorations ## Beta See a system's state and every change across time Plot enum and boolean Channels as a color-coded timeline with the [Enum Panel](/documentation/reference/explore-settings#panel-types). Each value period appears as a labeled band with its state name, so system behavior reads as named states over time. Enum Panel ## Beta Read every Channel's current value, live or at any point in time Display the most recent value for each plotted Channel as a tile with the [Stat Panel](/documentation/reference/explore-settings#panel-types). Values update in real time during Live mode and follow the time cursor when scrubbing through historical telemetry. * Updates automatically in Live mode or when hovering over another Panel * Supports numeric, boolean, enum, and bit field Channels * Works with Timeseries, Enum, Table, Geo Map, and File Viewer Panels Stat Panel ## Beta Pan, zoom, and render high-rate telemetry at full speed Enable [WebGL rendering](/documentation/reference/explore-settings#webgl-traces) in the Timeseries Panel for faster panning, zooming, and point rendering. Recommended for Windows and Linux users working with high-volume telemetry or high-rate Channels. WebGL traces # March 2026 Source: https://docs.siftstack.com/release-notes/2026/march-2026 New tools for comparison, export, and investigation This release adds data export, per-Channel downsampling controls, relative-time alignment, data source swapping, and the ability to plot and create Annotations in Explore, plus Calculated Channel support in Rules. ## New: Export data from any Timeseries Panel in CSV, Parquet, or WinPlot [Export](../../documentation/reference/explore-settings) data directly from any Timeseries Panel in Explore and move it into downstream tools without copying or reformatting. Choose the format that fits your pipeline: * **CSV** for broad compatibility, * **Parquet** for columnar analysis, or * **WinPlot** for signal-specific tooling. Export data from any Timeseries Panel in CSV, Parquet, or WinPlot ## New: Control how each Channel is downsampled in a Timeseries Panel Select any Channel in a Timeseries Panel to [set](../../documentation/reference/explore-settings) its downsampling method: * **LTTB** for preserving overall signal shape, * **Min/Max** for retaining true peaks and valleys, or * **Changed Only** for capturing state transitions in enum and boolean Channels. Control how each Channel is downsampled in a Timeseries Panel ## New: Swap a Run or Asset in Explore without rebuilding your Panels Replace the data source behind an investigation, **Run** or **Asset**, while keeping every Panel, layout, and setting intact. When new test data arrives, [swap](../../documentation/reference/explore-settings) the source and continue where you left off. Swap a Run or Asset in Explore without rebuilding your Panels ## Beta: Align Runs on a shared timeline to compare data across tests Offset Runs that happened at different times so they share a common reference point. * [Align](../../documentation/analyze/align-runs-comparison) to the **start or end of a Run**, * a specific **timestamp**, or * an **Annotation** within the Run, then compare behavior side by side on one timeline. Align Runs on a shared timeline to compare data across tests ## Beta: Plot and create Annotations directly on a Timeseries Panel [Plot](../../documentation/analyze/analyze-a-run) Annotations from an **Asset** or **Run** onto any Timeseries Panel and [create](../../documentation/analyze/analyze-a-run) new ones without leaving Explore. Mark a phase, flag a review, or pin an exact moment so the full context stays attached to the data. Plot and create Annotations directly on a Timeseries Panel ## Beta: Trigger Rules on Calculated Channels to alert on derived metrics Rules now accept Calculated Channels as inputs. Define thresholds and trigger alerts on derived metrics, not just raw telemetry Channels. # Control access, catch drift, and automate your thresholds Source: https://docs.siftstack.com/release-notes/2026/may-2026 Release notes · May 2026 This release puts you in control of who sees your telemetry, helps you catch Run drift with statistical baselines built from related Runs, and lets Rules and Calculated Channels use values from Asset and Run files. HDF5 and TDMS files now upload directly into Sift, and every new Panel in Explore opens with your preferred settings. ## New Give everyone exactly the right access to your telemetry Control telemetry access with [Attribute-Based Access Controls](/documentation/manage/set-up-data-access-governance). Tie view, edit, and share permissions on Assets, Channels, and Runs to the attributes your team already manages in your identity provider. * Share curated Assets, Channels, and Runs with your teammates * Give each team and region the right level of access to the same data * Access updates everywhere it applies when group membership changes in your identity provider Data Access Governance (DAG) ## New Start analyzing HDF5 and TDMS data the moment it lands in Sift Upload test data with HDF5 and TDMS imports. Both formats use the same upload flow, progress reporting, and error handling as CSV and Parquet. * Upload from the surface you already work in: UI, Python client, or CLI * HDF5 files upload as-is and are ready to analyze right away * All TDMS data types come through, including complex numbers, with TDMS file properties imported as metadata Import TDMS an HDF% files ## Beta Catch any Run that drifts from your baseline Compare related Runs with [Families](/documentation/analyze/families/overview). Align members to a shared reference event, such as an Annotation or Run start, and build a statistical baseline from their aggregated signal history. * Plot every Family member on a shared timeline in Explore to compare signal shapes and spot outliers * Compute aggregate statistics across member Runs, including average, minimum, maximum, and standard deviation * Build Rules that use Family statistics as dynamic thresholds, with results surfaced as Annotations in Reports Families ## Beta Configure and open every new Panel the way you work Set personal defaults with [User Settings](/documentation/reference/explore-settings#user-settings). Configure your display preferences once, and every new Panel in Explore applies them automatically. * Set global preferences such as default timezone and live data refresh * Choose defaults for each of the Panel types, including Timeseries, Table, and FFT * Pick from Channel Name Delimiter options to match how your team separates hierarchy in Channel names * Reset defaults per Panel type or across all types at once User settings ## Beta Make Rules and Calculated Channels adapt to every Run Replace hardcoded thresholds with [file references](/documentation/transform/reference-files-in-expressions) in Rules and Calculated Channel expressions. Read values directly from files attached to an Asset or Run, and each expression picks up the right constants for that Asset or Run. * Attach files to an Asset for values that hold steady across Runs, such as hardware limits or calibration offsets * Attach files to a Run for values that change between tests, such as test parameters or acceptance criteria * Works with CSV, JSON, YAML, and TXT formats Reference files in CEL expressions # Analyze with agents, keep tests visible, and follow every state Source: https://docs.siftstack.com/release-notes/2026/september-2026 Release notes · September 2026 This release connects your coding agent to Sift for ingestion, investigation, and approved write actions. It also keeps telemetry visible beside the hardware through network drops so you can move the Runs you choose into Sift when you're ready. You can also follow state changes, read current values, and mark important moments directly in Explore. ## Analyze telemetry from your coding agent Connect Claude Code, Codex, Cursor, or OpenCode to your Sift environment with the [Sift MCP](/documentation/cli/sift-mcp) server. Ask your agent to ingest and discover telemetry, run analyses and transformations, or create Sift resources from the interface you already use. * Install skills and register the Model Context Protocol (MCP) server with supported clients using a single Sift CLI command. * Keep tools that overwrite or archive existing disabled resources until you choose to enable them. * Protect sessions with context limits, filtered queries, and automatic retry backoff. Analyze telemetry from your coding agent ## Keep test telemetry visible through network drops Capture and inspect telemetry beside your hardware with [Sift Edge](https://www.siftstack.com/use-case/sift-edge). Your Runs are saved locally during an interruption, letting you upload the ones you choose to Sift once your connection returns. * Watch live and recent telemetry with low latency from a local desktop app. * Translate protocols on site, buffer telemetry, and replay it after reconnecting. * Continue the analysis in Sift beside your Rules, Reports, saved views, and Run history. Keep test telemetry visible through network drops ## Compare every state change on one shared timeline Plot enum and boolean Channels as labeled, color-coded periods with the [Enum Panel](/documentation/reference/explore-settings#panel-types). Give each Channel its own row so changes across the system stay aligned in time. * Scan labeled bands to see how long each Channel held a state. * Zoom into striped Multiple Values bands to resolve changes that share one pixel. Compare every state change on one shared timeline ## Track live values and scrub back through a test Display each Channel's latest value as a tile with the [Stat Panel](/documentation/reference/explore-settings#panel-types). Values update every second in Live mode and follow a shared time cursor during historical review. * Sync with a Timeseries Panel to read values at the hovered or focused time. * Look back up to 5 minutes to find the latest value for each Channel. Track live values and scrub back through a test ## Keep every review marker attached to its telemetry Mark a point or time range in a Run with [Annotations](/documentation/reference/explore-settings#annotations). Plot those markers on a Timeseries Panel or use one as the shared T-0 for Run comparison. * Create an Annotation from the telemetry and time range you are reviewing. * Align related Runs to the same event so behavior reads against one reference point. Keep every review marker attached to its telemetry # August 2025 Source: https://docs.siftstack.com/release-notes/august-2025 Accelerating the journey from data to decisions Each of this month's updates stands strong on its own, but together they tell a story about where Sift is headed. 1. If your pipelines produce data in [Parquet](#new%3A-parquet-file-support-for-telemetry-ingestion-in-the-ui-and-rest-api-beta), you can now bring it directly into Sift. 2. Once that data is inside, [Metadata](#new%3A-user-defined-metadata-for-consistent-organization%2Ffiltering-across-sift-resources), a new Sift feature, ensures it can be organized, managed, and easily found later, making reviews more automated and efficient. 3. From there, Explore v2 (Beta) becomes the place to work, transforming Parquet data into insights. Now, in Explore v2 (Beta), with [Live Mode, Sync Mode, and Views](#new%3A-explore-2-beta-expands-with-sync-mode%2C-live-mode%2C-and-views), teams can track signals in real time and uncover root causes faster. Individually, these updates add speed, structure, and efficiency. Together, they show Sift as the platform that turns raw data into organized review, live analysis, and shared insight without friction. Beyond these highlights, you will also find several other New and Improved updates described below. ## New: Explore 2 (Beta) expands with Sync mode, Live mode, and Views * **Overview**: Explore 2 (Beta) now expands with Live mode to stream data directly into the workspace and Sync mode to align a multi-panel view containing different Channels. When Sync mode is active, zooming into one panel automatically adjusts the others to the same time range. An early implementation of Views is also available in Explore 2 (Beta): you can apply Views created in Explore 1, with support for creating and editing Views planned for a future release (in Explore 2). These updates build on the foundation of Explore 2 (Beta), which delivers speed, precision, and control for high-frequency telemetry analysis. Live + Sync mode ## New: User-Defined Metadata for consistent organization/filtering across Sift resources * **Overview**: Sift now supports user-defined Metadata, allowing you to add structured key-value pairs to all resources including Runs, Assets, Annotations, Rules, Reports, Report Templates, Campaigns, Calculated Channels, and User-defined Functions. This provides a consistent way to describe and categorize resources beyond unstructured tags. * See the documentation on User-Defined Metadata: [Tutorial](../tutorials/manage/tutorial-2), [Reference](../documentation/manage/organize-and-filter-resources-with-metadata), and [How-to guide](../documentation/manage/get-alerted-when-a-limit-is-breached). Metadata ## New: Identity provider (IdP) (Beta) integration for scalable user management * **Overview**: Sift now integrates with external Identity Providers (IdPs) that support push provisioning. User and group changes in your IdP automatically synchronize to Sift, ensuring account information remains current without manual intervention. * See the documentation on Identity provider (IdP): [Tutorial](../tutorials/manage/tutorial-1), [Reference](../documentation/manage/connect-an-identity-provider), [How-to guide](../documentation/manage/connect-an-identity-provider). IdP ## New: A dedicated Jobs page for easier monitoring and results tracking * **Overview**: Sift now includes a dedicated Jobs page at `/manage/jobs`. This page provides a central location to view all Jobs in your organization as well as your own Jobs, making it easier to monitor progress, manage execution, review results, and take actions such as canceling or retrying Jobs. Jobs ## New: NaN and infinity handling for state-aware telemetry analysis * **Overview**: Sift now supports ingestion and analysis of `NaN`, `+Infinity`, and `-Infinity` values in float and double Channels. These values were previously filtered out and sent to the dead-letter queue (DLQ) but are now available in Rules, visualizations, and Calculated Channels. To ensure safe handling, new built-in functions `isnan`, `isinf`, and `isfinite` provide precise control. NaN ## New: Parquet file support for telemetry ingestion in the UI and REST API (Beta) * **Overview**: Sift now supports importing Parquet files through both the UI and the REST API. Parquet files can be ingested directly, with each Channel represented as a column in a flat schema. This makes it easier to bring telemetry from modern data pipelines into Sift. * See the Parquet ingestion docs: [Parquet uploads](../documentation/ingest/data-import/import-data-from-a-file). Parquet ## Improved: Support for 10 GiB exports with background notifications * **Overview**: You can now export large volumes of data directly from the Explore page, whether viewing a Run or an Asset. Exports are conducted in the background, and progress is visible in the Notifications dropdown and the Jobs page at `/manage/jobs`. Once the export is complete, you will receive a notification and can download the results without needing to monitor the process. At this time, exports are supported up to 10 GiB per Job. This safeguard can be adjusted for specific customer needs. Export 1 Export 2 ## Onboarding tutorial * **Overview**: New to Sift, or onboarding a new teammate? Sift now includes a beginner tutorial that introduces the basics of the platform and walks through an end-to-end workflow using real telemetry data. This tutorial is designed to help new users understand Sift quickly and make onboarding easier for your team. [Learn more](../learning-path/overview). # December 2025 Source: https://docs.siftstack.com/release-notes/december-2025 Clear correlation finding and modular logic This month's updates make it easier to analyze, reuse, and deepen telemetry insights. * You can now use the new Scatterplot Panel to analyze correlations between signals and more easily identify anomalies by visualizing multiple signals in a single view. * You can also now reference existing calculations (Calculated Channels) inside other Calculated Channels, a capability (Beta) that lets you build modularized logic with greater clarity. ## Uncover deep correlations with multi-dimensional visualization The Scatterplot Panel in Explore v2 (Beta) helps you discover relationships between signals by plotting multiple dimensions in a single view. This enables faster validation of correlations and clearer identification of outliers. If you regularly compare multiple signals or investigate unexpected changes, consider using the Scatterplot Panel in Explore v2 (Beta) to explore those relationships. Scatterplot Panel ## Beta Reference existing calculations to build more complex derived metrics You can now reference existing Calculated Channels as inputs to new ones, enabling more complex expressions while maintaining readability and modularity. This enables greater consistency and reduces the potential for errors when performing complex, repeated data transformations. If you regularly build derived metrics, consider referencing an existing Calculated Channel to create cleaner, more modular expressions. Calculated Channel # July 2025 Source: https://docs.siftstack.com/release-notes/july-2025 ## Overview This month's release notes introduce foundational upgrades across the Sift workspace. Explore 2 (Beta) is now live, delivering a rebuilt exploration experience with sharper visuals, faster performance, and more flexible workflows. We've also rolled out protective rate limiting for high-volume data access and brought back flexible Channel search for faster navigation. Together, these updates give teams deeper visibility, more reliable performance, and a smoother path from raw data to answers. ## New: Explore v2 (Beta) * **Overview**: Explore v2 (Beta) is a full rebuild of Sift's Explore workspace for telemetry analysis, designed for speed, precision, and control. Now available in Beta, this update enhances several aspects of the exploration workflow to help teams move faster, compare signals more effectively, and uncover root causes with less friction. It introduces capabilities such as multi-chart layouts, cross-source plotting, smarter Channel selection, advanced styling, and X+Y zoom, along with performance improvements including nanosecond resolution and significantly faster rendering, especially on Linux. The redesign is grounded in direct input from teams working with high-frequency, mission-critical data. * To learn more, see Explore v2 (Beta)'s [Tutorial](../tutorials/analyze/explore/tutorial-1). * **Unlocked**: Explore v2 (Beta) gives teams greater control and clarity when working with high-frequency telemetry. Whether you're troubleshooting a system fault, comparing behavior across Assets, or surfacing trends across large datasets, the new workspace is built to accelerate that process. The result: faster root cause analysis, clearer comparisons, and less time spent wrangling data. Explore 2 (Beta) ## New: GetData rate limiting * **Overview**: Sift now includes rate limiting for GetData requests across many of our interfaces, including the API, Grafana plugin, and Explore v1. This change is designed to protect system stability without disrupting normal usage, especially for users running automated or large-scale queries. * **Unlocked**: This feature introduces a protective layer that limits excessively parallel queries or long-running scripts that could affect performance for others. The rate limiter is configured with generous thresholds based on real usage data and has been running in dry-run mode for validation. Importantly, this does not apply to Explore v2 (Beta), which uses a separate data path. Teams relying on GetData via these interfaces should expect no impact under normal usage but will benefit from improved overall reliability. ## Restored: Keyword search in the Channel selector * **Overview**: Explore's Channel selector now supports keyword search using multiple partial terms. This restores a popular search behavior previously referred to as "fuzzy Channel search" by users. You can now locate Channels more efficiently, even when you don't remember the exact name or formatting. * **Unlocked**: You can search using multiple space-separated keywords, and each will be matched independently within the Channel name, regardless of order. For example, typing `max_ground temp` will successfully match `max_ground_temp(C)`. This improves discoverability for long or inconsistently named Channels and streamlines navigation across large datasets. Search ## Announcements * **Manifesto**: Ever wonder why Sift was created? It wasn't to build more software; it was to fix the fragile infrastructure that slows down the teams building our most complex machines. We've published a manifesto that lays out what we're building and why it matters. [Download manifesto](https://www.siftstack.com/manifesto). * **Webinar recording**: Traceability isn't just a compliance checkbox anymore; it's now mission-critical infrastructure. In our latest webinar, we break down how leading aerospace and defense teams are unifying hardware genealogy across build, test, and operations to move faster and reduce risk. Whether you missed the live session or want to revisit key insights, the full recording is now available [here](https://www.siftstack.com/mission-critical/payload-webinar). ## Recent blogs How Sift transforms hardware telemetry chaos into a trusted foundation for analysis
} > “Sift gives engineering teams a single foundation to work with hardware telemetry by delivering a \[Single Source of Truth (SSOT)] and a \[Single Pane of Glass (SPOG)].” # June 2025 Source: https://docs.siftstack.com/release-notes/june-2025 ## Overview This month's release notes introduce new ways to bring data into Sift and view it across your tools. You can now send data from LabVIEW and FlexLogger directly to Sift. The Sift Grafana plugin is also now available in the public plugin catalog for easy installation. Sift's workspace (Explore) now supports a logarithmic Y-axis scale, making it easier to inspect signals that span multiple orders of magnitude. ## New: Visualize Sift telemetry in Grafana via official plugin * **Overview**: The [Sift Grafana plugin](https://grafana.com/grafana/plugins/sift-grafana-datasource/) is now publicly available in the Grafana plugin catalog. It supports both simple Channel queries and Calculated Channel expressions, enabling teams to visualize Sift telemetry directly in Grafana dashboards without any manual installation. * **Unlocked**: With public catalog availability, teams no longer need to distribute or install the plugin manually. This update makes it easier to integrate Sift into existing dashboards and observability workflows, while continuing to pull structured telemetry from Sift's Single Source of Truth (SSOT) with full consistency and governance. Grafana ## New: Send data to Sift from LabVIEW and FlexLogger * **Overview**: Sift now offers official plugins for [LabVIEW](https://github.com/sift-stack/sift-labview/tree/main) and [FlexLogger](https://github.com/sift-stack/sift-labview/tree/main/plugins/flexlogger), enabling teams to send or upload engineering data from National Instruments environments directly into Sift for centralized analysis and observability. * **Unlocked**: Engineers can now send or upload data from LabVIEW and FlexLogger into Sift to unify telemetry from test and validation workflows. This closes the gap between data collection and analysis, making results easier to visualize, review, and trace all within a single platform. LabVIEW, FlexLogger, and Sift ## New: Log scale to view signals across multiple magnitudes * **Overview**: Explore now supports a logarithmic Y-axis scale, giving users a clearer view of signals (Channels) that span multiple orders of magnitude. * **Unlocked**: Log scale helps surface patterns and trends in high-dynamic-range data that might be flattened or hidden on a linear scale. Log ## Webinar: Track component history across systems Join us on **July 15 at 1:00 PM ET** for a live Payload webinar on closing the traceability gap in aerospace and defense programs. Industry experts including **Karthik Gollapudi**, CEO and Co-founder of Sift, will discuss how organizations are unifying genealogy tracking across test, production, and sustainment to reduce compliance risk and improve mission readiness. [Learn more and register](https://us06web.zoom.us/webinar/register/WN_i9yi-RggRVG-f3w3xheGJA#/registration). # May 2025 Source: https://docs.siftstack.com/release-notes/may-2025 ## Overview This month's release notes introduce a suite of impactful updates designed to enhance visibility, automation, and workspace organization in Sift. Highlights include the new Table Viewer, which provides a high-fidelity view of telemetry data; support for programmatic logic with external Rules; webhooks to trigger external workflows; the ability to archive Assets and Runs; and improved file uploads. These updates help streamline your workflows and enhance your ability to work with data efficiently. ## New: Trigger external workflows with webhooks (Beta) * **Overview**: Webhooks allow you to automatically trigger external workflows whenever a Rule condition is violated, enabling seamless integration between Sift and your operational stack. Built-in support for tools like Slack, PagerDuty, and more helps streamline responses to issues as they arise. To learn more, see [Webhooks (Beta)](../documentation/manage/get-alerted-when-a-limit-is-breached). * **Unlocked**: Rule violations can now trigger outbound webhooks, enabling automated connections between Sift and external systems, such as Microsoft Teams, Slack or PagerDuty. Webhooks ## New: View high-fidelity data in the Table Viewer (Beta) * **Overview**: The Table Viewer displays raw telemetry in a high-fidelity table format, allowing users to inspect and filter exact values aligned with time series charts. This structured view is ideal for pinpoint analysis and precise data review. * **Unlocked**: You can now perform detailed, time-aligned reviews of telemetry data, identify anomalies with greater precision, and correlate events across Channels using an interactive, filterable table view. Table Viewer ## New: Integrate external Rules into CI/CD workflows * **Overview**: External Rules let you evaluate custom logic on demand via the Sift API, making them ideal for automated and programmatic workflows like CI/CD. These Rules operate outside the UI, are temporary by design, and can produce Annotations that appear in Reports. * **Unlocked**: You can now automate Rule evaluation in pipelines, generate annotations programmatically, and integrate Sift's logic engine into external systems without relying on the UI. ## New: Archive Assets and Runs * **Overview**: You can now archive Assets and Runs in Sift to declutter your workspace without losing data. Archived items are hidden from the main view but remain accessible via the archive filter, preserving historical records while maintaining a clear day-to-day focus. * **Unlocked**: You can now streamline your workspace by hiding inactive or outdated items, stay focused on current work, and still retain access to complete historical context when needed. Archived Runs Archived Assets ## New: Monitor upload status and errors * **Overview**: Uploading CSV and TDMS files in Sift now shows real-time progress indicators and more explicit error messages. These enhancements enhance transparency, making it easier to diagnose and resolve issues during data import. * **Unlocked**: You can now confidently track file upload progress, quickly identify problems, and ensure smoother, more reliable data ingestion. Monitor upload status and errors ## Improvement: View documentation by domain and content type * **Overview**: The public-facing documentation has been reorganized into two main sections: *UI* and *API*. Each section is now structured around four content types: *Tutorials*, *How-to guides*, *Reference*, and *Explanations*. At launch, only the How-to guides and Reference materials are available, with Tutorials and Explanations to be added incrementally. * **Unlocked**: You can now find documentation more easily, with a clearer separation between UI and API content and a structure that aligns with best practices for accessibility and discoverability. ## Recent blogs Engineering at the speed of flight } > "We call it the new Sift world,” Blair said. “As soon as someone sees what it can do, they want in." Test like you fly starts with the data, not the dashboard } > "When observability and execution work together, CI/CD becomes more than a software metaphor. It becomes real." Why frequent, small releases strengthen hardware development } > "Frequent releases allow engineers to validate performance at every stage, reducing the likelihood of major failures right before launch." Why Impulse Space chose to build on Sift } > "Impulse is deploying Sift across their engineering workflows, allowing teams to work from a centralized source of truth and streamline their ability to review, analyze, and act on high-frequency mission data." # November 2025 Source: https://docs.siftstack.com/release-notes/november-2025 Clearer ways to understand telemetry changes ## Overview This month's updates reinforce our mission to make it easy to analyze, recreate, and act on the insights in your telemetry. * Explore v2 (Beta) now offers [improved performance and clearer interactions](#new:-accelerate-your-analysis-with-a-faster-explore-v2-beta), giving you a smoother experience when investigating live or historical data. * Within Explore v2 (Beta), the new Panel Configurations (Beta) feature lets you capture the precise setup of any Panel so you can [quickly recreate analyses](#new:-easily-recreate-and-share-visual-analyses) or apply them to new data. * And when you are not directly analyzing your telemetry, Webhooks (now generally available) notify you the moment [important changes](#new:-trigger-external-workflows-the-instant-something-important-happens-in-your-telemetry) occur in your live data. ## New Accelerate your analysis with a faster Explore v2 (Beta) Explore v2 (Beta) continues to evolve with upgrades that make it more responsive, intuitive, and stable across both live and historical analysis. Improvements span smoother real-time analysis, a clearer and more useful Table Panel, more flexibility in Charts, and simplified time range controls. [See the Changelog for full details](../changelog). Explore v2 (Beta) ## New Easily recreate and share visual analyses The new Panel Configurations (Beta) feature in Explore v2 (Beta) builds on and expands the capabilities previously offered by Views in Explore v1, providing more granular control, greater flexibility, and improved reusability across analysis workflows. They let you capture and reuse the complete visualization setup of an individual Panel, including Channel selections, axis mappings, color scales, hidden states, and styling preferences. [Learn more](../documentation/reference/explore-settings). Panel Configurations
Contact us to join the Beta.
## New Trigger external workflows the instant something important happens in your telemetry Webhooks are now generally available, making it easy to integrate Sift with your external tools and trigger actions based on telemetry. By automatically sending real-time events when a live Rule is violated and resolved, Webhooks connect Sift directly with your existing software tools, such as Microsoft Teams, Slack, Jira, OpsGenie, and PagerDuty. [Learn more](../documentation/manage/get-alerted-when-a-limit-is-breached). Webhooks ## Recent blogs ### Working at Sift: Alexa Agnew “Before transitioning into engineering, \[at Sift, Alexa] led analytics and infrastructure products at ABL Space Systems and Carta, and earlier worked as a quantum engineer and deployment lead at Rigetti Computing. With a PhD in physics from Columbia, where she conducted research at the Nobel Prize–winning LIGO lab, … Alexa recently made the leap from product management to full-time software development at Sift to build the tools that accelerate some of the most ambitious hardware programs in the world.” [Read blog](https://www.siftstack.com/mission-critical/working-at-sift-alexa-agnew). ### Working at Sift: Mike Casey "Before joining Sift, Mike spent nearly a decade as an intelligence analyst at the Defense Intelligence Agency, where he focused on Chinese space, satellite, and AI-enabled military capabilities. His Mandarin-language research and C4ISR expertise directly informed national security decisions and technology investments. At Sift, he’s traded policy reports for launch pads, working side by side with engineers to help hardware teams move faster and smarter." [Read blog](https://www.siftstack.com/mission-critical/working-at-sift-mike-casey). ## Looking ahead We're excited to deliver these improvements and features to you and your team. We're looking forward to hearing how these capabilities shape the way you work. # October 2025 Source: https://docs.siftstack.com/release-notes/october-2025 Connecting data, insight, and support ## Overview This month's release strengthens the connection between how data enters Sift and how teams stay supported while working in it. Parquet file ingestion, previously in beta, is now generally available, making it easier to move high-volume, structured data from collection to analysis in [Explore v2 (Beta)](./july-2025#new%3A-explore-v2-beta). When something in that process needs attention, the new Sift Support experience makes it easy to get help right where you work. Teams can now report and track issues directly within the app, creating a single source of truth for communication and visibility. The Changelog is updated regularly with smaller fixes and performance improvements. Visit anytime to explore what's new between releases. ## New: Simplify data ingestion with Parquet file support, now generally available Parquet file ingestion, previously in beta, is now generally available in both the Sift UI and REST API. This update makes it easier to bring high-volume, structured Parquet data directly into Sift for faster analysis. Once ingested, you can use Explore v2 (Beta) to dive deeper into your data. [Learn more](../documentation/ingest/data-import/import-data-from-a-file). Parquet ## New: Obtain direct in-app support with full issue tracking We've introduced Sift Support as the centralized way to manage support within the Sift app. It serves as the single source of truth for reporting issues, tracking progress, and communicating with our team. Users can follow their own requests, and an assigned admin can view all open issues across the organization to maintain visibility and ensure timely resolution. Pylon ## Recent blogs * [Bringing automation to orbit determination with Sift](https://www.siftstack.com/mission-critical/orbit-determination-with-sift) * “The challenge \[with orbit determination] is \[the need] to transform \[its] data into actionable insight. Instead of manually combing through plots or spreadsheets, engineers use Sift to ingest, visualize, and automatically evaluate orbit determination performance. The result is a repeatable workflow that allows teams to verify positioning accuracy with confidence and speed.” * [Why I joined Sift: Russ Parrish](https://www.siftstack.com/mission-critical/russ-parrish) * "‍Russ Parrish is the Head of Design at Sift, where he leads product and brand execution for tools that help hardware engineers test, build, and operate advanced hardware. Over the last 15 years, he's worked across aerospace, robotics, and AI, including roles at SpaceX, Intuitive Surgical, and IBM.” # Release notes Source: https://docs.siftstack.com/release-notes/overview Stay up to date with the latest major montly updates ### Analyze with agents, keep tests visible, and follow every state This release connects your coding agent to Sift for ingestion, investigation, and approved write actions. It also keeps telemetry visible beside the hardware through network drops so you can move the Runs you choose into Sift when you're ready. You can also follow state changes, read current values, and mark important moments directly in Explore. [Learn more](../release-notes/2026/september-2026). ### Import flight logs, reuse investigations, and shape your Channel tree Bring PX4 flight logs into Sift in their native format, reopen any Explore session exactly as you left it, and control how Channel names build your Channel tree. [Learn more](../release-notes/2026/august-2026). ### New Panels, faster rendering, and Saved Explorations This release ships Sift CLI v0.2.0 with HDF5 and TDMS imports, Parquet export, and built-in documentation. It also adds two new Panel types and performance improvements to the Timeseries Panel in Explore. Explorations can now be saved and reused across Runs, Assets, and Families. [Learn more](../release-notes/2026/july-2026). ### Control access, catch drift, and automate your thresholds This release puts you in control of who sees your telemetry, helps you catch Run drift with statistical baselines built from related Runs, and lets Rules and Calculated Channels use values from Asset and Run files. HDF5 and TDMS files now upload directly into Sift, and every new Panel in Explore opens with your preferred settings. [Learn more](../release-notes/2026/may-2026). April 2026 ships a rebuilt Explore workspace, the ability to use Calculated Channels in Rule logic, and support for referencing Calculated Channels within other Calculated Channel calculations. [Learn more](../release-notes/2026/april-2026). This release adds data export, per-Channel downsampling controls, relative-time alignment, data source swapping, and the ability to plot and create Annotations in Explore, plus Calculated Channel support in Rules. [Learn more](../release-notes/2026/march-2026). This release makes Sift more capable and easier to use by helping engineers analyze telemetry in context. [Learn more](../release-notes/2026/february-2026). This month, we are launching new features that give you more precise control over your telemetry. These capabilities make it easier to share targeted visual reviews and export data for external analysis. [Learn more](../release-notes/2026/january-2026).
2025
This month's updates make it easier to analyze, reuse, and deepen telemetry insights. [Learn more](../release-notes/december-2025). This month's updates reinforce our mission to make it easy to analyze, recreate, and act on the insights in your telemetry. [Learn more](../release-notes/november-2025). This month's release strengthens the connection between how data enters Sift and how teams stay supported while working in it. [Learn more](../release-notes/october-2025). This month's updates build on last month's momentum, bringing faster data ingestion, richer insights, and simpler ways to access your data once it's saved. Together, they highlight how Sift continues to streamline the path from collection to insight. [Learn more](../release-notes/september-2025). Each of this month's updates stands strong on its own, but together they tell a story about where Sift is headed. [Learn more](../release-notes/august-2025). This month's release notes introduce foundational upgrades across the Sift workspace. [Learn more](../release-notes/july-2025). This month's release notes introduce new ways to bring data into Sift and view it across your tools. [Learn more](../release-notes/june-2025). This month's release notes introduce a suite of impactful updates designed to enhance visibility, automation, and workspace organization in Sift. [Learn more](../release-notes/may-2025). # September 2025 Source: https://docs.siftstack.com/release-notes/september-2025 Faster data ingestion, rich insights: simpler access ## Overview This month's updates build on last month's momentum, bringing faster data ingestion, richer insights, and simpler ways to access your data once it's saved. Together, they highlight how Sift continues to streamline the path from collection to insight. 1. Faster ingestion. Telemetry points are now stored in the database faster. Tail latency for point ingestion has been [cut in half](#improved%3A-faster-telemetry-point-ingestion), making data available more quickly for analysis and downstream processing. 2. Richer insights. Once your data is stored, Explore v2 (Beta) lets you convert it into actionable insights using [new panels](#new%3A-explore-v2-beta-expands-with-geomap%2C-histogram%2C-and-fft-panels%2C-bulk-assignments%2C-and-table-enhancements). The additions of GeoMaps, Histograms, and FFT (Fast Fourier Transform) panels provide ways to analyze telemetry, whether you're tracking location, studying distributions, or examining signals in the frequency domain. 3. Simpler access. After your data is stored in a Run, accessing it is easier. You can now [export a Run's Channels](#new%3A-export-a-run’s-channels-from-its-overview-page) directly from its Overview page for provenance and custom analysis, reducing unnecessary steps while maintaining transparent data access. ## New: Explore v2 (Beta) expands with GeoMap, Histogram, and FFT panels, Bulk Assignments, and Table enhancements * GeoMap (Beta) panel: In Explore v2 (Beta), you can now use GeoMap panels to explore telemetry by location, enabling spatial analysis of data across regions. * Histogram panel: You can now create Histogram panels to analyze distribution patterns in telemetry signals. * FFT (Fast Fourier Transform) panel: Explore v2 (Beta) now includes an FFT panel for frequency-domain analysis, helping identify signal characteristics and periodic behaviors. * Bulk Assignments: You can now configure multiple Channels at once, reducing repetitive work. * Int64 and Uint64 support: Explore v2 (Beta) supports int64 and uint64 data types for high-range values. * Performance improvements: Channel List and Tree views are now faster, improving navigation and workflows. * UTC offset: You can display UTC offsets in Time Series and Table panels, ensuring consistent time alignment. * Table panel enhancements: Tables now include text wrapping for text Channels, smart auto-scaling of column widths, and a fix to the Show Carried Values toggle. * Context Menu in a Table panel: You can now right-click column values in the Table panel to remove a Channel or copy a cell value to the clipboard. * Date Range Picker updates (Table panel only): The Date Range Picker in Table panel settings has been fixed so that selected ranges apply correctly after “save and close.” It now also includes a Set to Full Range option for easier configuration. demo
The primary distinction is that v2 builds on v1's foundation with a redesigned experience that introduces: * **New capabilities**: Multi-chart layouts, cross-source plotting (Runs and Assets), smarter Channel selection, advanced styling, and X+Y zoom. * **Performance improvements**: Nanosecond resolution, faster rendering, and can plot significantly more Channels and data points. * **User-centered design**: Built from feedback of teams working with high-frequency, mission-critical data. ## New: Export a Run's Channels from its Overview page * **Overview**: You can now export Channel data straight from a Run's Overview page, eliminating the need to open Explore and plot Channels first. This streamlines access to Run data and reduces unnecessary steps, enabling faster workflows and simpler selection of all Channels in a Run. demo ## New: Download a Run's original data file from its Overview page * **Overview**: When a Run is created by importing a CSV, TDMS, or Parquet file, the original file is now available as an attachment. This improves data provenance, makes it easier to validate the source of your Runs, and provides convenient access for off-Sift analysis. You can download the file directly from the Runs Overview page or from the Run details in Explore v1/v2 (Beta). demo ## Improved: Faster telemetry point ingestion * **Overview**: Telemetry points are now stored in the database faster. Tail latency for point ingestion has been cut in half (from \~1s to under 500ms at the 99.99th percentile), making data available more quickly for analysis and downstream processing. ## Improved: Simplified notifications menu * **Overview**: The Notifications menu was redesigned to provide a consistent experience: where applicable, notifications include a direct link to their destination, while purely informational notifications appear as text only. For example, being tagged in an Annotation will now give you a direct link to open it. The Notifications menu was also cleared to only include the most relevant information, and unnecessary details were removed to make notifications simpler and easier to scan. In-progress and completed Jobs were also removed and are now accessible from the Jobs page. ## Recent blog * [Scale now or pay later](https://www.siftstack.com/mission-critical/scale-now-or-pay-later) “Sift was purpose-built to address precisely what these generic solutions \[like ClickHouse, InfluxDB, TimescaleDB] overlook: nested structures, evolving schemas, extreme cardinality, and consistent performance throughout the entire telemetry lifecycle.” # Getting started with Explore (legacy) Source: https://docs.siftstack.com/tutorials/analyze/explore-v1/tutorial-1 Learn how to work with Explore (legacy) In this tutorial, you'll learn how to organize and explore telemetry data using Explore v1. ## Prerequisites * Download the [rover.csv](https://drive.google.com/file/d/1_8MXmOcT2vLh1zXE6uThX-bYytN4XGBS/view?usp=sharing) file. ## Step 1: Import data 1. Select **Runs** in the navigation, then click **Import data**. 2. Upload the **rover.csv** file. 3. Click **New Asset**. 4. In the **Asset** box, enter: ``` fl_rover-asset ``` Replace `fl` with your initials (first and last name). This helps avoid naming conflicts if others are also completing the tutorial on the same Sift instance. 5. In the **Run** box (New), edit the Run name with the following: ``` fl_rover-run ``` Again, replace `fl` with your initials to ensure the Run name is unique within your workspace. 6. Click **Upload**. 7. Click **Close** ## Step 2: Plot data 1. In the **Runs name or description** box, enter the following: ``` fl_rover-run ``` 2. In the **Runs** table, click **fl\_rover-run**. 3. Click **Explore Legacy**. 4. In the **Channels** section, click the following Channels: * **battery\_charge** * **vehicle\_state** 5. Click **Other charts**. 6. Select **Table Viewer**. 7. In the **Channels** section, under **camera\_2**, click the following Channels: * **current** * **temperature** ## Conclusion In this tutorial, you learned how to organize and explore telemetry data using Explore v1. # Getting started with Explore Source: https://docs.siftstack.com/tutorials/analyze/explore/tutorial-1 Build your first multi Panel workspace to visualize and understand your data In this tutorial, you will get started with [Explore](/documentation/reference/explore-settings) by using [Panels](/documentation/reference/explore-settings#panel-types) to analyze telemetry data from a Low Earth Orbit (LEO) satellite. You will visualize Channels, build a flexible, [multi-Panel layout](/documentation/reference/explore-settings#layout), and learn how to share your analysis to collaborate with others. ## Prerequisites * Import [this](https://drive.google.com/uc?export=download\&id=1FWTLYMzxRNRNUESuLgHWBU0HHJsfXlFk) CSV file (`leo.csv`) to Sift, creating a new Asset named `leo_satellite` and a Run named `leo_satellite_simulation` * If you are unsure how to import a CSV, see [Import a CSV](/documentation/ingest/data-import/import-data-from-a-file) for step by step instructions. ## Step 1: Open your data Open your dataset in Explore: 1. Select **Runs** in the navigation, then search for and select **leo\_satellite\_simulation**. 2. Click **Explore**. ## Step 2: Build a multi-Panel layout Panels let you visualize and analyze your data in Explore. Use a **Timeseries** Panel to view trends and a **Table** Panel to inspect values, then create a multi-Panel layout to better understand your data. Other Panel types are also available. See [Panels](/documentation/reference/explore-settings#panel-types). 1. Click the **Timeseries** Panel. 2. In the **Channels** tab, under the **EPS** section, click: * **Battery\_Current** * **Solar\_Array\_Current** 3. Click **Add**, then select **Timeseries**. 4. In the **Channels** tab, under the **Payload** section, click: * **Payload\_Power\_Draw** 5. Click **Add**, then select **Table**. 6. In the **Channels** tab, under the **Comms** section, click the following Channels: * **Data\_Backlog** * **Downlink\_Data\_Rate** * **Downlink\_SNR** * **Tx\_Power** 7. Drag the **Table 1** tab to the bottom of the workspace. 8. Drag the **Timeseries 2** tab to the bottom right. ## Step 3: Share your workspace Share your workspace to let others view the same Panels and layout: 1. Click **Share**. 2. Click **Copy**. ## Conclusion In this tutorial, you used Explore to build a multi-Panel layout to analyze telemetry data. You learned how to visualize Channels, use Panels to explore your data, and share your workspace to collaborate with others. # Getting started with streaming data to Sift using Python Source: https://docs.siftstack.com/tutorials/ingest/tutorial-1 Learn how to send live telemetry from a Python script to Sift and view it in real time This tutorial shows how to stream telemetry from a Python script to Sift using the [Sift Python client library](https://sift-stack.github.io/sift/python/latest/). You will install the client library, configure authentication, define telemetry signals, and send time-series data to Sift from a Python script. ## Prerequisites * Basic understanding of how [Assets](../../documentation/ingest/stream/organize-streamed-data-into-assets-and-runs), [Channels](../../documentation/reference/channels-reference), and [Runs](../../documentation/reference/runs-reference) relate to each other in Sift * Working knowledge of Python and familiarity with `async` / `await` * A Sift [API key](../../documentation/manage/set-up-api-access) and your Sift [gRPC and REST base URLs](../../documentation/manage/set-up-api-access) ## Scenario Imagine a robotic vehicle that continuously reports telemetry such as velocity and internal temperature. In this tutorial, a Python script simulates the system by generating these measurements every 0.5 seconds. ## Step 1: Obtain the Python example project Clone the Sift repository and navigate to the directory that contains the Python streaming ingestion example used in this tutorial, including the script and a `requirements.txt` file that lists the dependencies required to run it. ```bash theme={null} git clone https://github.com/sift-stack/sift.git cd sift/python/examples/ingestion-tutorial ``` ## Step 2: Install the Python dependencies From a Python environment, run the following command to install the dependencies required for the Python streaming ingestion example: ```bash theme={null} pip install -r requirements.txt ``` ## Step 3: Configure authentication Create a `.env` file and add your Sift API key along with your Sift gRPC and REST URLs: ```bash id="v9s3dk" theme={null} touch .env ``` ```bash id="8b2c6p" theme={null} SIFT_API_KEY=your_api_key_here SIFT_GRPC_URL=https://your-grpc-url SIFT_REST_URL=https://your-rest-url ``` ## Step 4: Run the example and view streamed data in Sift Run the Python script to start streaming telemetry to Sift. The script runs continuously until you stop it (for example, with Ctrl+C), and the telemetry appears live in [Explore](/documentation/reference/explore-settings): ```bash theme={null} python stream.py ``` 1. Check the terminal for the generated Run name (for example, **robot\_vehicle\_…\_run**). Then, in **Sift**, locate the **Run name or description** field and enter that name. 2. Click **Explore**. 3. Click **Live**. 4. In the **Channels** tab, select the following Channels: * **temperature** * **velocity** ## Step 5: Understand the ingestion workflow The ingestion process follows a clear sequence. The steps below summarize how telemetry is structured, configured, and streamed to Sift. * At a high level, streaming telemetry to Sift involves defining structure first, then sending timestamped data that conforms to that structure. * In this script, authentication is configured using `SiftConnectionConfig`, and a `SiftClient` is created to communicate with your Sift environment. * A `FlowConfigPy` defines the telemetry schema, and each `ChannelConfigPy` declares an individual signal with its name, unit, and data type. * These types are used directly from `sift_stream_bindings` to avoid the CPU-bound overhead of the ergonomic Python type conversions. **Performance**: Using `sift_stream_bindings` types directly avoids the CPU-bound bottlenecks that occur when converting between `Flow` and `FlowPy` types. * An `IngestionConfigFormPy` associates that schema with an Asset, and a `RunCreate` defines the session that will group all incoming telemetry. * Once this ingestion context is established, the script opens a streaming ingestion session over gRPC and begins sending timestamped flows in real time. * Each flow is constructed directly as a `FlowPy` object using `ChannelValuePy`, `ValuePy`, and `TimeValuePy` from `sift_stream_bindings`, ensuring the data matches the defined schema. These flows are transmitted over the open stream and immediately appear in Sift under the specified Run. **Performance:** `ingest_client` should be opened once and reused for the entire duration of your program. Recreating it per batch or per iteration creates a new ingestion config each time, which introduces significant performance overhead. ## Conclusion In this tutorial, you cloned a Python example project, installed its dependencies, configured authentication, and streamed telemetry to Sift using the Sift Python client library. You also viewed the live telemetry in Explore and saw how streaming ingestion sends structured time-series data to Sift in real time. # Getting started with streaming data to Sift using Rust Source: https://docs.siftstack.com/tutorials/ingest/tutorial-2 Learn how to send live telemetry from a Rust application to Sift and view it in real time This tutorial shows how to stream telemetry from a Rust application to Sift using the [Sift Stream Rust library](https://crates.io/crates/sift_stream). You will install the library, configure authentication, define telemetry signals, and send time-series data to Sift from a Rust application. ## Prerequisites * Basic understanding of how [Assets](../../documentation/ingest/stream/organize-streamed-data-into-assets-and-runs), [Channels](../../documentation/reference/channels-reference), and [Runs](../../documentation/reference/runs-reference) relate to each other in Sift * Working knowledge of Rust and familiarity with async programming * A Sift [API key](../../documentation/manage/set-up-api-access) and your Sift [gRPC base URL](../../documentation/manage/set-up-api-access) ## Scenario Imagine a robotic vehicle that continuously reports telemetry during operation. The vehicle produces two signals: its current velocity and its internal temperature. In this tutorial, a Rust application simulates this system by generating measurements every 0.5 seconds and streaming them to Sift. ## Step 1: Obtain the Rust example project Clone the Sift repository and navigate to the `sift_stream` crate directory, which contains the `Cargo.toml` file for the streaming client library and the Rust example used in this tutorial: ```bash theme={null} git clone https://github.com/sift-stack/sift.git cd sift/rust/crates/sift_stream ``` ## Step 2: Configure authentication Create a `.env` file so the Rust example can authenticate with your Sift environment. Add your Sift API key and gRPC URL as environment variables: ```bash theme={null} touch .env ``` ```bash theme={null} SIFT_API_KEY=your_api_key_here SIFT_GRPC_URL=https://your-grpc-url ``` ## Step 3: Run the application and view streamed data in Sift Run the Rust example to start streaming telemetry to Sift. The example runs for about 10 minutes before stopping automatically. 1. From the `sift_stream` directory (the folder containing `Cargo.toml`), run the example: ```bash theme={null} cargo run --example ingestion-tutorial ``` 2. Check the terminal for the generated Run name (for example, **robot\_vehicle\_...\_run**). Then, in **Sift**, locate the **Run name or description** field and enter that name. 3. In the **Runs** table, click the Run name. 4. Click **Explore**. 5. Click **Live**. 6. In the **Channels** tab, select the following Channels: * **temperature** * **velocity** ## Step 4: Understand the ingestion workflow The ingestion process follows a sequence that defines the telemetry structure, establishes an ingestion session, and streams timestamped data to Sift. * The application begins by loading authentication credentials from the `.env` file using `dotenvy`. These values are used to create a `Credentials` configuration that allows the client to authenticate with your Sift environment. * A streaming client is then initialized using `SiftStreamBuilder`, which establishes the ingestion connection and prepares the client to send telemetry. * Telemetry sent to Sift must follow a defined schema. In this example, a `FlowConfig` defines the telemetry structure, and each `ChannelConfig` represents an individual signal. * Two Channels are defined: velocity and temperature. These Channels are grouped together within a Flow named `vehicle_metrics`. * An `IngestionConfigForm` associates the telemetry schema with an Asset and a unique client key. A `RunForm` then defines the session that groups incoming telemetry. * The Run is created as part of the same streaming ingestion session initialized by `SiftStreamBuilder`. This means the Run is established on the same connection used to send telemetry data. * Once the ingestion context is established, the application begins generating mock telemetry values and sending them to Sift using `sift_stream.send()`. Each message is sent as a `Flow` containing: * a timestamp * the Flow name * values for each Channel * After the loop completes, the program calls `finish()` to ensure any queued telemetry is transmitted before the streaming session closes. ## Conclusion In this tutorial, you streamed telemetry from a Rust application to Sift using the Sift Stream Rust library. You configured authentication, defined telemetry signals, and sent timestamped data to Sift in real time. You also viewed the live telemetry in Sift to understand how streamed data appears during ingestion. # Integrate an Identity Provider (IdP) with Sift Source: https://docs.siftstack.com/tutorials/manage/tutorial-1 Learn how to integrate an external IdP with Sift using Microsoft Entra ID This tutorial shows how to integrate an external Identity Provider (IdP) with Sift using Microsoft Entra ID as an example. The same process applies to other IdPs that support push provisioning. After setup, your IdP can synchronize external groups and manage their permissions in Sift. ## Prerequisites * Administrator access to Sift. * Administrator access to your Identity Provider (IdP). * IdP integration enabled for your Sift account by your Sift account representative. ## Step 1: Understand IdP integration in Sift Sift integrates with Identity Providers (IdPs) that support **push provisioning** to keep groups synchronized. After setup, Sift automatically syncs with your IdP every 24 hours, and you can also run a manual sync. Groups provisioned from an IdP appear in Sift as **external groups**. You can manage their permissions in Sift, but membership must be managed in the IdP. IdPs that require pull provisioning, such as Google Workspace, require custom integration. ## Step 2: Generate the SCIM endpoint URL and access token in Sift After IdP integration is enabled for your account, generate the SCIM credentials needed to connect your IdP to Sift. 1. Click your profile icon, which shows the first initial of your account name. 2. Select **Manage**. 3. Click **Manage Identity Provider**. 4. Click **Generate Token**. 5. Copy URL: In the **SCIM Server URL** section, click **Copy**. 6. Copy token: In the **Token** section, click **Copy**. 7. Click **Close**. ## Step 3: Configure your IdP (Microsoft Entra ID) Use the SCIM credentials generated in Sift to configure your IdP. In Microsoft Entra ID, enter the **SCIM Server URL** in the **Tenant URL** field and the **Token** in the **Secret Token** field. Save the configuration, test the connection, and start provisioning. After provisioning begins, changes from your IdP will sync to Sift during the next automatic or manual sync. ## Step 4: Sync and verify external groups in Sift Rather than waiting 24 hours for the automatic sync, run a manual sync to import external groups into Sift immediately. 1. Click **Manage Identity Provider**. 2. Click **Sync Organization**. ## Conclusion You integrated an Identity Provider (IdP) with Sift using Microsoft Entra ID. External groups can now sync to Sift, where you can manage their permissions. Group membership must be managed in the IdP and will sync to Sift automatically or through a manual sync. The same process can be used for other IdPs that support push provisioning. ## Resources * [Identity Provider (IdP) settings](/documentation/reference/manage/idp-settings) * [Connect an Identity Provider (IdP) to Sift](/documentation/manage/connect-an-identity-provider) # Getting started with Metadata in Sift Source: https://docs.siftstack.com/tutorials/manage/tutorial-2 Learn how to create Metadata keys and filter resources in Sift In this tutorial, you'll create and apply Metadata in Sift, then use it to filter a Run. Metadata helps you organize resources using consistent key-value pairs across your workspace. ## Prerequisites * At least one Run in your workspace ## Step 1: Understand Metadata in Sift Metadata in Sift uses key-value pairs to organize and filter resources across your workspace. Each Metadata key is defined once and assigned a data type to ensure consistent values. Metadata values support three data types: **string**, **number**, and **boolean**. You can apply Metadata to the following resources: **Runs**, **Assets**, **Annotations**, **Rules**, **Reports**, **Report Templates**, **Campaigns**, **Calculated Channels**, and **User-Defined Functions**. ## Step 2: Create a Metadata key Let's create a numeric Metadata key. 1. Click your profile icon, which shows the first initial of your account name. 2. Select **Manage**. 3. In the **Manage** navigation menu, click **Metadata**. 4. Click **+ Create Metadata Key**. 5. In the **Name** box, enter the following: ``` priority_level ``` 6. In the **Type** list, select **number**. 7. Click **Create**. ## Step 3: Add a Metadata key to a Run Now, let's add the created Metadata key to a Run. 1. Select **Runs** in the navigation. 2. In the **Runs** table, click the name of a Run to add the Metadata key you just created. Later in [Step 5](#step-5-optional-remove-metadata-key), you will have the option to remove the Metadata key. For now, we will use this Run as an example to demonstrate how Runs, like all Sift resources, can support Metadata. 3. Click **Edit**. 4. Click **+ Add Metadata**. 5. In the **Select or create key** list, select **priority\_level**. 6. In the **Enter number** list, enter the following (where `1` on the 1-5 scale refers to high priority): ``` 1 ``` 7. Click **Save changes**. ## Step 4: Locate a Run by its Metadata key Let's locate the Run using the **priority\_level** Metadata key. 1. Select **Runs** in the navigation, then click **Metadata**. 2. In the **Select key** list, select **priority\_level**. 3. In the **Enter number** box, enter **1**. ## Step 5 (optional): Remove Metadata key To remove the Metadata key added to the Run, consider the following steps: 1. In the Run's overview page, click **Edit**. 2. In the **Metadata** section, locate the **priority\_level** key. 3. Click **Remove**. 4. Click **Save changes**. ## Conclusion You created a Metadata key, applied it to a Run, and used it to filter resources in Sift. Metadata helps you organize your workspace and quickly locate the data you need. ## Resources * Reference: [Metadata](../../documentation/manage/organize-and-filter-resources-with-metadata) * How-to guide: [Manage Metadata](../../documentation/manage/organize-and-filter-resources-with-metadata) # Tutorials Source: https://docs.siftstack.com/tutorials/overview Explore step-by-step tutorials that show you how to use Sift's full range of features and capabilities Send telemetry to Sift from a Python script or a Rust application. Send live telemetry from a Python script to Sift and view it in real time. Send live telemetry from a Rust application to Sift and view it in real time. Explore telemetry data using Explore, Sift's visualization workspace. Explore telemetry data using Explore (legacy). Build a multi-Panel workspace to visualize and understand your telemetry. Control access to your workspace and organize resources for faster searching. Integrate an external Identity Provider (IdP) with Sift using Microsoft Entra ID. Create Metadata keys and use them to filter resources in Sift. Use attribute-based access control (ABAC) to restrict access to specific resources.