Skip to content

Indexes

The Index API exposes identity management, methodology exploration, cadence-specific canonical history, declared related MetaTables, and a preview-first deletion workflow. Business behavior lives under msm.services.indices; apps/v1 is a typed HTTP adapter.

An Index is a reusable observable. It is not automatically an Asset, pricing instrument, or Portfolio. USD_SWAP_10Y, for example, is one Index identity whose one-minute and daily observations live in two different canonical datasets.

flowchart LR
    I["IndexTable
USD_SWAP_10Y identity"] --> M["Optional methodologies
definitions and legs"] I --> D1["IndexValuesTS.1m
physical 1m table"] I --> D2["IndexValuesTS.1d
physical 1d table"] D1 --> V1["Intraday values frame"] D2 --> V2["Daily values frame"] I -. "optional replication" .-> P["Portfolio
holdings and execution"]

Routes

Method Path Operation ID Result
GET /api/v1/index-type/ listIndexTypes Paginated type registry
GET /api/v1/index-type/{index_type}/ getIndexType One type
GET /api/v1/index/ listIndexes Counted Index page
POST /api/v1/index/ createIndex New plain or externally calculated identity
GET /api/v1/index/{uid}/ getIndex One Index
PATCH /api/v1/index/{uid}/ updateIndex Updated mutable identity fields
GET /api/v1/index/{uid}/summary/ getIndexSummary FrontEndDetailSummary
GET /api/v1/index/{uid}/methodologies/ listIndexMethodologies Definition history
GET /api/v1/index/{uid}/methodologies/{definition_uid}/ getIndexMethodology Exact definition and ordered legs
GET /api/v1/index/{uid}/datasets/ listIndexDatasets Canonical cadence descriptors
GET /api/v1/index/{uid}/datasets/{meta_table_uid}/ getIndexDatasetSummary Bounded aggregate summary
GET /api/v1/index/{uid}/datasets/{meta_table_uid}/values/ getIndexDatasetValuesFrame core.tabular_frame@v1
GET /api/v1/index/{uid}/related-meta-tables/ listIndexRelatedMetaTables Core and extension declarations
GET /api/v1/index/{uid}/delete-impact/ getIndexDeleteImpact Compatibility impact only
POST /api/v1/index/bulk-delete/preview/ previewBulkDeleteIndexes Read-only reviewed plan
POST /api/v1/index/bulk-delete/ bulkDeleteIndexes Reviewed saga execution
DELETE /api/v1/index/{uid}/ deleteIndex Deprecated reviewed single-item execution

Every operation is included in the Adapter from API connection contract. previewBulkDeleteIndexes is classified as a query even though it uses POST; create, update, and deletion execution are mutations.

Listing And Selection

GET /api/v1/index/ supports search, index_type, provider, has_definition, has_canonical_values, cadence, limit, and offset. The response count is authoritative for the complete filter, and ordering is stable.

Creating an Index does not create methodology or storage. Use DerivedIndex.upsert(...) when core owns a reproducible methodology. Register cadence storage through the migration workflow before a producer writes values.

What listIndexDatasets Returns

GET /api/v1/index/{uid}/datasets/ is not a value query. It returns a typed catalog of tables that can be selected for summary, browsing, or reviewed cleanup. A descriptor includes:

meta_table_uid
identifier and namespace
cadence and physical_table_name
time_index_name and index_names
columns
verified foreign_keys
storage_kind and discovery_source
view/edit access state
producer identifiers
scoped-delete capability

A table qualifies as canonical only when the registered cadence contract maps to the authoritative configured_index_values_storage(cadence=...) model and that SQLAlchemy/Alembic model contains the real foreign key:

index_identifier -> IndexTable.unique_identifier

The resolver also verifies identifier, cadence, physical table, grain, and the required value and unit columns. A matching column name or physical-name prefix is never enough.

The 1m and 1d descriptors for USD_SWAP_10Y therefore identify different MetaTable UIDs and physical tables even though both are filtered with the same Index business identifier.

Bounded Values

The values route requires timezone-aware start and end, an asc or desc order, and a limit from 1 through 5,000. It resolves the selected Index UID and always adds this backend filter:

index_identifier = selected Index.unique_identifier

The implementation uses a governed compiled SELECT with time bounds and a server-side LIMIT. The SDK APIDataNode.get_df_between_dates(...) API does not expose a row-limit argument in SDK 4.4.32, so it is not used here to read a full history and truncate in application memory. The response is the SDK TabularFrameResponse and can feed generic Command Center tables and charts.

Extension-Owned Relationships

Extensions register IndexRelationshipProvider objects. Providers must supply an authoritative SQLAlchemy model with a real FK to IndexTable.uid or IndexTable.unique_identifier; they do not have to inherit any core Index DataNode. Exploration and deletion are separate opt-ins. Inferred candidates remain informational and can never become delete targets automatically.

Safe Deletion

Direct unreviewed deletion is disabled. The supported flow is:

flowchart TB
    S["Select explicit Index UIDs"] --> P["POST bulk-delete/preview"]
    P --> W["Display table counts, time bounds, access, relationships, and warnings"]
    W --> A{"Exact phrase and every required warning acknowledged?"}
    A -- "No" --> N["No mutation"]
    A -- "Yes" --> E["POST bulk-delete with token and idempotency key"]
    E --> R["Rebuild scope and verify actor, signature, expiry, and access"]
    R --> T["Scoped delete_after_date with index_identifier list"]
    T --> I["Delete identity after restrictive storage is clear"]
    I --> J["Persist per-step result in execution journal"]

Preview modes are values_only, identity_only, and identity_and_values. Preview is non-mutating and returns:

  • every selected Index and canonical cadence table;
  • resolved-leg provenance when identity-and-values cleanup must clear dynamic component and coefficient audit rows;
  • authoritative affected counts and time bounds, or an explicit unavailable state;
  • declared and inferred relationships;
  • an executable/blocking decision;
  • stable warning codes and required acknowledgements;
  • an exact confirmation phrase;
  • a short-lived, signed, actor- and scope-bound token.

Execution rechecks the current scope and platform edit authority. Value deletion calls TimeIndexMetaTable.delete_after_date(None, dimension_filters={"index_identifier": [...]}); it never truncates a table or uses a raw/compiled SQL delete against DataNode storage.

Deletion across MetaTables is a saga, not one transaction. The IndexDeletionExecutionTable stores idempotency, state, and completed steps so retries do not expand scope. It stores no token, signing secret, or observation values.

Deployment requires the SDK-generated migration for that journal and a managed Secret injected as MSM_INDEX_DELETE_CONFIRMATION_SECRET with at least 32 characters. Do not release the destructive routes until both are present and the migrated journal binding is verified.

Deleting values does not reset DataNode hashes, checkpoints, update statistics, jobs, schedules, or producer configuration. Values can be republished. Pause producers before destructive cleanup and use the producer's repair/backfill workflow afterward.

The deprecated single-item DELETE route requires the same reviewed payload. Calling it without request-bound identity or preview confirmation returns 401 or 428; it has no unsafe fallback.