Skip to main content
AnomalyArmor speaks the Open Data Contract Standard (ODCS) v3.1.0. Every asset’s monitoring config (freshness SLAs, validity rules, schema, metrics, drift monitors, alert rules, destinations, blackouts) is exportable as ODCS YAML and re-importable later. Three things this gives you:
  1. Interoperability. ODCS is a Linux Foundation project. Soda, Great Expectations, and dbt speak it. Your contract isn’t a proprietary blob.
  2. No lock-in. Click Export, get a directory of YAML. Import it into whichever tool you pick next. No rewrite required.
  3. Version control. Contracts diff cleanly in Git. Reviewers see which validity rule changed in a PR, not a screenshot of a settings page.

ODCS-native vs ODCS-extended

ODCS covers the core concepts every tool agrees on: schema, column quality rules, freshness SLAs, ownership. We use its sanctioned customProperties extension mechanism for the AnomalyArmor-specific concepts ODCS doesn’t have a native slot for.
Native ODCS (any tool reads these)Extended (under customProperties.anomalyarmor)
apiVersion, id, name, version, status, domain, tagsSchema drift monitoring (ODCS has no schema-change concept)
schema[] with properties[] + physicalTypeML distribution drift (PSI, KS, chi-squared)
quality[] metric library (nullValues, invalidValues, duplicateValues, rowCount)Row-count anomaly detection with rolling baselines
quality[] custom SQLAlert rules and routing
slaProperties[] (latency, frequency)Destinations (Slack, email, PagerDuty, Linear, webhooks)
team[]Operating schedules and blackout windows
Our exported YAML is fully ODCS-compliant: it passes the official v3.1.0 JSON Schema validator. Using customProperties is exactly how Soda and Great Expectations handle the same tension: industry-standard, not a workaround.

Portability modes

Two export modes control what gets written to the YAML.

extended (default)

Full round-trip fidelity. Includes customProperties.anomalyarmor.<domain> blocks with every AA-specific configuration knob (drift thresholds, monitoring modes, alert routing, etc.). Use this for version control, backup, and re-import into AnomalyArmor.

odcs-pure

Strips every customProperties.anomalyarmor block. The resulting YAML contains only the ODCS-native subset that any ODCS tool can read and act on: schema, quality rules, freshness SLAs, team. You lose the AA-extended features (drift, alert routing, blackouts) but gain maximum portability for the interop case. Pick odcs-pure when you want to hand the contract to a Soda or Great Expectations customer. Pick extended everywhere else.

CLI

pip install anomalyarmor-cli
armor auth login --key aa_live_your_key_here

One asset to stdout

armor contract pull --asset <asset-uuid>
Writes ODCS YAML to stdout. Pipe to yq or redirect to a file.

One asset to a file

armor contract pull --asset <asset-uuid> -o orders.yaml

Whole warehouse as a zip

armor contract pull --warehouse analytics -o analytics.zip
Submits an async job, polls to completion, and writes the zip. Layout inside the zip:
analytics/
  contract/
    orders.yaml
    customers.yaml
    invoices.yaml

Every contract in your account

armor contract pull --all -o everything.zip

Filtering

Include or exclude specific config domains:
# Only freshness + validity
armor contract pull --asset <uuid> --include freshness,validity -o partial.yaml

# Everything except alert routing and destinations
armor contract pull --asset <uuid> --exclude alert_rules,destinations -o no-alerts.yaml
Registered domain names: schema, freshness, validity, metrics, row_count, drift_monitors, schema_drift, alert_rules, destinations, blackouts.

ODCS-pure mode

armor contract pull --asset <uuid> --mode odcs-pure -o orders.odcs.yaml

REST API

Three endpoints power the CLI. All authenticated via your API key.

Single-asset export (synchronous)

GET /api/v1/contracts/{asset_public_id}/export
    ?mode=extended|odcs-pure     (default: extended)
    &include=freshness,validity  (comma-separated, default: all)
    &exclude=alert_rules         (applied after include)
Returns application/x-yaml with a Content-Disposition: attachment header.

Bulk export (asynchronous)

POST /api/v1/contracts/export-jobs
  { "scope": "warehouse"|"all",
    "scope_name": "analytics",        // required for scope=warehouse
    "mode": "extended",
    "include": ["freshness"],
    "exclude": ["alert_rules"] }
Returns {"job_id": "<uuid>"}. Poll with:
GET /api/v1/contracts/export-jobs/{job_id}
Response includes status, progress_percent, and asset_count. When status is completed, download:
GET /api/v1/contracts/export-jobs/{job_id}/download
Returns application/zip with the laid-out {warehouse}/{schema}/{table}.yaml archive.

Round-trip example

# Export
armor contract pull --asset <uuid> -o orders.yaml

# Edit the freshness threshold in orders.yaml
vim orders.yaml

# Commit to Git
git add orders.yaml && git commit -m "tighten freshness SLA on orders"

# Import (Phase 2, coming soon)
# armor contract apply --file orders.yaml
Import (armor contract apply) is in active development. Contracts exported today will apply cleanly when it ships.

Coming from Soda?

Soda ships ODCS export as of 2024. Run soda export --odcs on your existing Soda project and the resulting YAML imports directly into AnomalyArmor once the import flow ships.

What’s not supported yet

  • Import (armor contract apply). Export-only today; import ships in the next milestone.
  • Per-table granularity. One contract covers the whole warehouse; per-table will land with the import PR.
  • S3 artifact storage for huge bulk exports. Jobs today inline the zip bytes in the status response, which is fine for hundreds of tables; company-wide exports with thousands of tables should use multiple scope-warehouse jobs until S3 storage lands.