openapi: 3.0.0
info:
title: ThoughtSpot Public REST 10.1.0.cl 26.8.0.cl API
version: '2.0'
servers:
- url: '{base-url}'
variables:
base-url:
default: https://localhost:443
security:
- bearerAuth: []
tags:
- name: 26.8.0.cl
paths:
/api/rest/2.0/ai/memory/export:
post:
operationId: exportMemory
description: "\nExports memory entries (rules, recipes, and always-apply rules) for\nthe specified data-models as a single YAML payload. The payload can\nbe edited locally and re-submitted through `importMemory`.\nRequires Spotter access (use/manage) and either edit or memory\naccess on corresponding data model sources. <br/> <span class=\"since-beta-tag\">Beta</span> <span class=\"since-beta-tag\">Version: 26.8.0.cl or later</span>\n\nThis API allows users to export data-model memories for a given list of data-models. This exported yaml file can then be modified and used as input to the import API in target env.\n\nThis API enables customers to migrate memories from a source env to a target env. This improves memory adoption for Spotter by giving the users a chance to develop their memories in one env and replicate the same in another env.\n\n#### Usage guidelines\n\nTo export memory for one or more data-models, the request may include:\n- `sources`: A list of typed scope groups identifying which data-models to export memory for. Each group contains:\n - `type`: The source object type for this group — `DATA_MODEL`.\n - `identifiers`: An array of GUIDs or human-readable `obj_id`s of the data-models to export memory for. obj_ids are resolved server-side before forwarding.\n\nThe API returns a response object with:\n- `content`: The serialized memory payload (YAML) — exactly the shape that the `importMemory` API consumes. Edit it locally and pass it back through `importMemory` to apply changes.\n\n#### Source Type\n\n- **DATA_MODEL**: The `identifiers` are data-model GUIDs. This is the default source type for Spotter memory and covers the rules, recipes and always-apply rules attached directly to a data-model.\n\n#### File format\n\nThe exported `content` is a YAML document with a single top-level `memories` key holding a list of memory items — exactly the format the `importMemory` API consumes. The full format reference (an annotated example, memory item fields, per-type content, and `datamodel_sources` identification) is documented in the `importMemory` API's **File format** section. Exported files populate each source's `guid` and, if present, `obj_id` as well.\n\n#### Error responses\n\n| Code | Description |\n|------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| 401 | Unauthorized — authentication token is missing, expired, or invalid. |\n| 403 | Forbidden — the authenticated user does not have necessary permissions, or lacks read access on a referenced data-model, or the bearer token does not correspond to the data-model's org. |\n\n> ###### Note:\n> - To use this API, the user needs Spotter access (use/manage) and either edit or memory access on the data-model and they must use corresponding org related bearerToken where the data-model exists.\n> - This endpoint is currently in Beta. Breaking changes may be introduced before the endpoint is made Generally Available.\n> - Available from version 26.8.0.cl and later.\n> - This endpoint requires Spotter — please contact ThoughtSpot Support to enable Spotter on your cluster.\n\n\n\n\n#### Endpoint URL\n"
tags:
- 26.8.0.cl
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ExportMemoryRequest'
required: true
parameters: []
responses:
'200':
description: Common successful response
content:
application/json:
schema:
$ref: '#/components/schemas/ExportMemoryResponse'
examples:
example_1:
summary: Serialized YAML memory payload returned
value:
content: "memories:\n- type: RULE\n content:\n rule_definition: \"Earnings: total sales filtered to West region only.\"\n datamodel_sources:\n - guid: 33333333-3333-3333-3333-333333333333\n obj_id: sales-model\n tags: []\n- type: RULE\n content:\n rule_definition: \"Geographic data is organized in a three-level hierarchy from broadest to most specific: Region (highest level) → State (middle level) → County (lowest level). This hierarchical structure enables progressive drill-down analysis, where each level provides increasingly granular geographic segmentation for sales and quantity metrics.\"\n datamodel_sources:\n - guid: 33333333-3333-3333-3333-333333333333\n obj_id: sales-model\n tags: []\n- type: RULE\n content:\n rule_definition: \"Hot products: top 5 products by total sales (no region filter applied).\"\n datamodel_sources:\n - guid: 33333333-3333-3333-3333-333333333333\n obj_id: sales-model\n tags: []\n- type: RECIPE\n content:\n user_query: Calculate earnings for East region current year\n recipe: \"{\\\"task\\\": \\\"Compute earnings by extracting sales and filtering to East region for the current year\\\", \\\"steps\\\": [{\\\"instruction\\\": \\\"Extract sales, then apply a filter for current year and a filter for East region.\\\", \\\"analytical_mappings\\\": {\\\"tml_tokens\\\": [\\\"[sales] [date] = 'this year' [region] = 'east'\\\"], \\\"formulas\\\": []}}]}\"\n datamodel_sources:\n - guid: 33333333-3333-3333-3333-333333333333\n obj_id: sales-model\n tags: []\n- type: RECIPE\n content:\n user_query: Total sales for East region current year\n recipe: \"{\\\"task\\\": \\\"Compute total sales filtered to East region for the current year\\\", \\\"steps\\\": [{\\\"instruction\\\": \\\"Calculate total sales where region is East and date is current year.\\\", \\\"analytical_mappings\\\": {\\\"tml_tokens\\\": [\\\"[sales] [date] = 'this year' [region] = 'east'\\\"], \\\"formulas\\\": []}}]}\"\n datamodel_sources:\n - guid: 33333333-3333-3333-3333-333333333333\n obj_id: sales-model\n tags: []\n- type: RECIPE\n content:\n user_query: What is the total quantity purchased by city and region?\n recipe: \"{\\\"task\\\":\\\"Calculate total quantity purchased grouped by city and region\\\",\\\"steps\\\":[{\\\"instruction\\\":\\\"Sum the quantity purchased metric and group the results by city and region to show purchasing volumes across different geographic locations\\\",\\\"analytical_mappings\\\":{\\\"tml_tokens\\\":[\\\"[quantity purchased] [city] [region]\\\"],\\\"formulas\\\":[]}}]}\"\n datamodel_sources:\n - guid: 33333333-3333-3333-3333-333333333333\n obj_id: sales-model\n tags: []\n- type: RECIPE\n content:\n user_query: What were total jacket sales in 2024?\n recipe: \"{\\\"task\\\":\\\"Compute the aggregate 2024 jacket sales revenue.\\\",\\\"steps\\\":[{\\\"instruction\\\":\\\"Shows the total sales revenue for jackets in 2024. This provides a high-level metric to understand overall jacket sales performance for the year.\\\",\\\"analytical_mappings\\\":{\\\"tml_tokens\\\":[\\\"[sales] [item type] = [item type].\\\\\\\"jackets\\\\\\\" [date] = \\\\\\\"2024\\\\\\\"\\\"],\\\"formulas\\\":[]}}]}\"\n datamodel_sources:\n - guid: 33333333-3333-3333-3333-333333333333\n obj_id: sales-model\n tags: []\n- type: RECIPE\n content:\n user_query: How are monthly sales and quantity tracking by state?\n recipe: \"{\\\"task\\\":\\\"Aggregate monthly sales and quantity by state for a state-level performance view.\\\",\\\"steps\\\":[{\\\"instruction\\\":\\\"Shows monthly sales and quantity purchased metrics organized by state. Provides a state-wise view of sales performance with additional dimensional context.\\\",\\\"analytical_mappings\\\":{\\\"tml_tokens\\\":[\\\"[sales] [quantity purchased] [state] [date]\\\"],\\\"formulas\\\":[]}}]}\"\n datamodel_sources:\n - guid: 33333333-3333-3333-3333-333333333333\n obj_id: sales-model\n tags: []\n- type: RECIPE\n content:\n user_query: \"What's the quarterly sales and quantity by region and state for the last 3 years, with yearly rollups?\"\n recipe: \"{\\\"task\\\":\\\"Build a 3-year quarterly view of sales and quantity grouped by region and state, with quarterly and yearly aggregation.\\\",\\\"steps\\\":[{\\\"instruction\\\":\\\"Displays quarterly performance metrics including sales and quantity purchased, broken down by region and state over the last 3 years. Enables analysis of regional and state-level trends with both quarterly and yearly views.\\\",\\\"analytical_mappings\\\":{\\\"tml_tokens\\\":[\\\"[sales] [quantity purchased] [region] [state] [date].\\\\\\\"quarterly\\\\\\\" [date].\\\\\\\"last 3 years\\\\\\\" [date].\\\\\\\"yearly\\\\\\\"\\\"],\\\"formulas\\\":[]}}]}\"\n datamodel_sources:\n - guid: 33333333-3333-3333-3333-333333333333\n obj_id: sales-model\n tags: []\n- type: RECIPE\n content:\n user_query: How are we doing against quarterly sales and quantity targets per region?\n recipe: \"{\\\"task\\\":\\\"Render bullet charts contrasting quarterly actual vs target sales and quantity per region.\\\",\\\"steps\\\":[{\\\"instruction\\\":\\\"Compares actual quarterly sales and quantity metrics against targets by region using bullet charts. Provides a target vs actual performance view to track progress.\\\",\\\"analytical_mappings\\\":{\\\"tml_tokens\\\":[\\\"[sales] [quantity purchased] [region] [date].\\\\\\\"quarterly\\\\\\\" [Target sales] [Target quantity]\\\"],\\\"formulas\\\":[\\\"{\\\\\\\"name\\\\\\\": \\\\\\\"Target sales\\\\\\\", \\\\\\\"expression\\\\\\\": \\\\\\\"random ( ) * sum ( sales ) * 2\\\\\\\"}\\\",\\\"{\\\\\\\"name\\\\\\\": \\\\\\\"Target quantity\\\\\\\", \\\\\\\"expression\\\\\\\": \\\\\\\"random ( ) * sum ( quantity purchased ) * 2\\\\\\\"}\\\"]}}]}\"\n datamodel_sources:\n - guid: 33333333-3333-3333-3333-333333333333\n obj_id: sales-model\n tags: []\n"
example_2:
summary: Serialized YAML memory payload returned
value:
content: "memories:\n- type: RULE\n content:\n rule_definition: \"Earnings: total sales filtered to West region only.\"\n datamodel_sources:\n - guid: 33333333-3333-3333-3333-333333333333\n obj_id: sales-model\n tags: []\n- type: RULE\n content:\n rule_definition: \"Hot products: top 5 products by total sales (no region filter applied).\"\n datamodel_sources:\n - guid: 33333333-3333-3333-3333-333333333333\n obj_id: sales-model\n tags: []\n- type: RULE\n content:\n rule_definition: \"Geographic data is organized in a three-level hierarchy from broadest to most specific: Region (highest level) → State (middle level) → County (lowest level). This hierarchical structure enables progressive drill-down analysis, where each level provides increasingly granular geographic segmentation for sales and quantity metrics.\"\n datamodel_sources:\n - guid: 33333333-3333-3333-3333-333333333333\n obj_id: sales-model\n tags: []\n- type: RULE\n content:\n rule_definition: \"When analyzing quantity purchased, apply a date filter for the last 3 years.\"\n datamodel_sources:\n - guid: 44444444-4444-4444-4444-444444444444\n obj_id: sample-model\n tags: []\n- type: RULE\n content:\n rule_definition: User's total sales target is 1 million USD.\n datamodel_sources:\n - guid: 44444444-4444-4444-4444-444444444444\n obj_id: sample-model\n tags: []\n- type: RULE\n content:\n rule_definition: Sales analyses must filter to east region only.\n datamodel_sources:\n - guid: 44444444-4444-4444-4444-444444444444\n obj_id: sample-model\n tags: []\n- type: RECIPE\n content:\n user_query: Calculate earnings for East region current year\n recipe: \"{\\\"task\\\": \\\"Compute earnings by extracting sales and filtering to East region for the current year\\\", \\\"steps\\\": [{\\\"instruction\\\": \\\"Extract sales, then apply a filter for current year and a filter for East region.\\\", \\\"analytical_mappings\\\": {\\\"tml_tokens\\\": [\\\"[sales] [date] = 'this year' [region] = 'east'\\\"], \\\"formulas\\\": []}}]}\"\n datamodel_sources:\n - guid: 33333333-3333-3333-3333-333333333333\n obj_id: sales-model\n tags: []\n- type: RECIPE\n content:\n user_query: Total sales for East region current year\n recipe: \"{\\\"task\\\": \\\"Compute total sales filtered to East region for the current year\\\", \\\"steps\\\": [{\\\"instruction\\\": \\\"Calculate total sales where region is East and date is current year.\\\", \\\"analytical_mappings\\\": {\\\"tml_tokens\\\": [\\\"[sales] [date] = 'this year' [region] = 'east'\\\"], \\\"formulas\\\": []}}]}\"\n datamodel_sources:\n - guid: 33333333-3333-3333-3333-333333333333\n obj_id: sales-model\n tags: []\n- type: RECIPE\n content:\n user_query: What is the total quantity purchased by city and region?\n recipe: \"{\\\"task\\\":\\\"Calculate total quantity purchased grouped by city and region\\\",\\\"steps\\\":[{\\\"instruction\\\":\\\"Sum the quantity purchased metric and group the results by city and region to show purchasing volumes across different geographic locations\\\",\\\"analytical_mappings\\\":{\\\"tml_tokens\\\":[\\\"[quantity purchased] [city] [region]\\\"],\\\"formulas\\\":[]}}]}\"\n datamodel_sources:\n - guid: 33333333-3333-3333-3333-333333333333\n obj_id: sales-model\n tags: []\n- type: RECIPE\n content:\n user_query: \"What's the quarterly sales and quantity by region and state for the last 3 years, with yearly rollups?\"\n recipe: \"{\\\"task\\\":\\\"Build a 3-year quarterly view of sales and quantity grouped by region and state, with quarterly and yearly aggregation.\\\",\\\"steps\\\":[{\\\"instruction\\\":\\\"Displays quarterly performance metrics including sales and quantity purchased, broken down by region and state over the last 3 years. Enables analysis of regional and state-level trends with both quarterly and yearly views.\\\",\\\"analytical_mappings\\\":{\\\"tml_tokens\\\":[\\\"[sales] [quantity purchased] [region] [state] [date].\\\\\\\"quarterly\\\\\\\" [date].\\\\\\\"last 3 years\\\\\\\" [date].\\\\\\\"yearly\\\\\\\"\\\"],\\\"formulas\\\":[]}}]}\"\n datamodel_sources:\n - guid: 33333333-3333-3333-3333-333333333333\n obj_id: sales-model\n tags: []\n- type: RECIPE\n content:\n user_query: How are we doing against quarterly sales and quantity targets per region?\n recipe: \"{\\\"task\\\":\\\"Render bullet charts contrasting quarterly actual vs target sales and quantity per region.\\\",\\\"steps\\\":[{\\\"instruction\\\":\\\"Compares actual quarterly sales and quantity metrics against targets by region using bullet charts. Provides a target vs actual performance view to track progress.\\\",\\\"analytical_mappings\\\":{\\\"tml_tokens\\\":[\\\"[sales] [quantity purchased] [region] [date].\\\\\\\"quarterly\\\\\\\" [Target sales] [Target quantity]\\\"],\\\"formulas\\\":[\\\"{\\\\\\\"name\\\\\\\": \\\\\\\"Target sales\\\\\\\", \\\\\\\"expression\\\\\\\": \\\\\\\"random ( ) * sum ( sales ) * 2\\\\\\\"}\\\",\\\"{\\\\\\\"name\\\\\\\": \\\\\\\"Target quantity\\\\\\\", \\\\\\\"expression\\\\\\\": \\\\\\\"random ( ) * sum ( quantity purchased ) * 2\\\\\\\"}\\\"]}}]}\"\n datamodel_sources:\n - guid: 33333333-3333-3333-3333-333333333333\n obj_id: sales-model\n tags: []\n- type: RECIPE\n content:\n user_query: How are monthly sales and quantity tracking by state?\n recipe: \"{\\\"task\\\":\\\"Aggregate monthly sales and quantity by state for a state-level performance view.\\\",\\\"steps\\\":[{\\\"instruction\\\":\\\"Shows monthly sales and quantity purchased metrics organized by state. Provides a state-wise view of sales performance with additional dimensional context.\\\",\\\"analytical_mappings\\\":{\\\"tml_tokens\\\":[\\\"[sales] [quantity purchased] [state] [date]\\\"],\\\"formulas\\\":[]}}]}\"\n datamodel_sources:\n - guid: 33333333-3333-3333-3333-333333333333\n obj_id: sales-model\n tags: []\n- type: RECIPE\n content:\n user_query: What were total jacket sales in 2024?\n recipe: \"{\\\"task\\\":\\\"Compute the aggregate 2024 jacket sales revenue.\\\",\\\"steps\\\":[{\\\"instruction\\\":\\\"Shows the total sales revenue for jackets in 2024. This provides a high-level metric to understand overall jacket sales performance for the year.\\\",\\\"analytical_mappings\\\":{\\\"tml_tokens\\\":[\\\"[sales] [item type] = [item type].\\\\\\\"jackets\\\\\\\" [date] = \\\\\\\"2024\\\\\\\"\\\"],\\\"formulas\\\":[]}}]}\"\n datamodel_sources:\n - guid: 33333333-3333-3333-3333-333333333333\n obj_id: sales-model\n tags: []\n- type: RECIPE\n content:\n user_query: What were jacket sales by region in 2024?\n recipe: \"{\\\"task\\\":\\\"Break out 2024 jacket sales revenue by region to compare regional performance.\\\",\\\"steps\\\":[{\\\"instruction\\\":\\\"Shows jacket sales revenue broken down by region for 2024. This helps identify which geographic regions are performing best in jacket sales and enables regional performance comparison.\\\",\\\"analytical_mappings\\\":{\\\"tml_tokens\\\":[\\\"[sales] by [region] [item type] = [item type].\\\\\\\"jackets\\\\\\\" [date] = \\\\\\\"2024\\\\\\\"\\\"],\\\"formulas\\\":[]}}]}\"\n datamodel_sources:\n - guid: 44444444-4444-4444-4444-444444444444\n obj_id: sample-model\n tags: []\n- type: RECIPE\n content:\n user_query: \"Show me quarterly sales and quantity trends over the past 3 years, newest first.\"\n recipe: \"{\\\"task\\\":\\\"Plot quarterly sales and quantity trends for the past 3 years in reverse chronological order.\\\",\\\"steps\\\":[{\\\"instruction\\\":\\\"Presents quarterly sales and quantity purchased trends over the last 3 years, sorted by most recent periods first. Enables time-based analysis of sales performance.\\\",\\\"analytical_mappings\\\":{\\\"tml_tokens\\\":[\\\"[sales] [quantity purchased] [date].\\\\\\\"quarterly\\\\\\\" [date].\\\\\\\"last 3 years\\\\\\\"\\\"],\\\"formulas\\\":[]}}]}\"\n datamodel_sources:\n - guid: 44444444-4444-4444-4444-444444444444\n obj_id: sample-model\n tags: []\n"
'201':
description: Common error response
content:
application/json:
schema:
$ref: '#/components/schemas/ExportMemoryResponse'
'400':
description: Operation failed
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized access.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: Forbidden access.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Operation failed
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/api/rest/2.0/ai/memory/import:
post:
operationId: importMemory
description: "\nImports memory entries (rules, recipes, and always-apply rules) from\na YAML payload, typically a payload produced by `exportMemory` and\nedited locally. The imported entries replace the existing memory for\nthe data-models referenced in the payload.\n`dry_run` is required. Pass `true` first to validate the payload and\nreview the preview counts and any row-level failures without making\nchanges, then re-run with `dry_run = false` to apply the import. An\nimport is not applied if any row fails validation.\nRequires Spotter access (use/manage) and either edit or memory\naccess on corresponding data model sources. <br/> <span class=\"since-beta-tag\">Beta</span> <span class=\"since-beta-tag\">Version: 26.8.0.cl or later</span>\n\nThis API allows users to import data-model memories using a given yaml file. This yaml file can be obtained from the export memory API in source env and can be modified and used as input to the import API in target env.\n\nThis API enables customers to migrate memories from a source env to a target env. This improves memory adoption for Spotter by giving the users a chance to develop their memories in one env and replicate the same in another env.\n\n#### Usage guidelines\n\nTo import memory, the request must include:\n- `content`: The full serialized memory payload to import (YAML). Typically the `content` value returned by the `exportMemory` API, edited locally and re-submitted. The payload itself identifies which data-models the memory applies to, so no separate identifier list is required.\n- `dry_run`: Required. When `true`, validate the payload and return preview counts without writing anything; when `false`, apply the import. Always run with `dry_run = true` first, then re-run with `dry_run = false` once you are satisfied with the preview.\n\nThe import replaces the existing global memories on the data-models referenced in the payload with the entries supplied in the payload.\n\nThe API returns a response object with:\n- `status`: The terminal status of the import (`SUCCESS`, `VALIDATION_FAILED`, or `FAILED`).\n- `summary`: Per `(memory_type, source)` counts. In a dry run the `deleted_record_count`/`inserted_record_count` are previews; in a real import they are actuals. On `VALIDATION_FAILED`, `summary` is `null` when validation fails before any item is processed (e.g. an unresolved or inaccessible data-model source) and an empty list otherwise — treat both as \"no counts available\".\n- `validation_failures`: Per-item validation failures, each with `line_number`, `reason`, `field_name`, and `message` for click-to-locate and inline highlighting.\n- `diagnostics`: Groups of diagnostic messages, each with a `sub_status` (`WARNING`, `FAILURE`, `ROLLED_BACK`, or `UNKNOWN`) and a `messages` list. This is the single channel for both non-fatal warnings (under `WARNING`, e.g. when some older memory entries could not be fully cleaned up) and fatal causes (e.g. the failure reason under `FAILURE`, or a `ROLLED_BACK` group when new entries were undone).\n- `operation_id`: A server-generated identifier for this import operation; include it when contacting support to help correlate server-side logs. Populated once the server registers the import operation; `null` when the request fails earlier (e.g. while parsing the payload or resolving its data-model sources).\n\n#### File format\n\nThe payload is a YAML document with a single top-level `memories` key holding a list of memory items. Each item is self-contained: a `type`, a typed `content` block, a `datamodel_sources` list, and optional `tags`. Typically you don't hand-author this file — you obtain it from `exportMemory`, edit it, and submit it back through `importMemory`.\n\n```yaml\nmemories:\n- type: RULE\n content:\n rule_definition: \"Always filter revenue to closed-won deals.\"\n datamodel_sources:\n - guid: 11111111-1111-1111-1111-111111111111\n obj_id: sales_data_model\n tags:\n - finance\n- type: RULE\n content:\n rule_definition: \"Exclude internal test accounts from all results.\"\n datamodel_sources:\n - obj_id: sales_data_model\n- type: RECIPE\n content:\n user_query: \"top accounts by revenue\"\n recipe: |\n {\"steps\": [...serialized recipe blob...]}\n datamodel_sources:\n - obj_id: sales_data_model\n- type: RECIPE\n content:\n user_query: \"monthly new customer count\"\n recipe: |\n {\"steps\": [...serialized recipe blob...]}\n datamodel_sources:\n - obj_id: sales_data_model\n- type: ALWAYS_APPLY_RULES\n content:\n rules:\n - \"Never show internal test accounts.\"\n - \"Round currency to whole dollars.\"\n datamodel_sources:\n - guid: 22222222-2222-2222-2222-222222222222\n```\n\nA file can contain multiple `RULE` and multiple `RECIPE` items for a data-model, but at most one `ALWAYS_APPLY_RULES` item per data-model.\n\n##### Memory item fields\n\n| Field | Required | Type | Description |\n|-------|----------|------|-------------|\n| `type` | Yes | String enum | One of `RULE`, `RECIPE`, or `ALWAYS_APPLY_RULES`. |\n| `content` | Yes | Mapping | Type-specific content block (see below). |\n| `datamodel_sources` | Yes | Non-empty list | The data-model(s) the memory attaches to. |\n| `tags` | No | List of strings | Free-form labels. |\n\n##### Memory types and content\n\n| `type` | Content fields | Notes |\n|--------|----------------|-------|\n| `RULE` | `rule_definition` — required, non-empty string | A single semantic rule. |\n| `RECIPE` | `recipe` and `user_query` — both required, non-empty strings | `recipe` is an opaque serialized blob; `user_query` is the natural-language query it answers. |\n| `ALWAYS_APPLY_RULES` | `rules` — required, non-empty list of non-empty strings | Data-model-wide always-apply rules. At most one `ALWAYS_APPLY_RULES` item per data-model. |\n\n##### Identifying data-models (`datamodel_sources`)\n\nEach item must list at least one source. Each entry identifies a data-model by at least one of:\n- `guid` — the data-model GUID.\n- `obj_id` — a stable object ID, resolved to a GUID server-side.\n\nIf both are supplied, `obj_id` takes precedence and `guid` is ignored entirely; `guid` takes effect only when `obj_id` is absent. Exported files populate `guid` and, if present, `obj_id` as well.\n\n> ⚠️ **Cross-environment import:** When `obj_id` is present it is\n> authoritative — the accompanying `guid` is **not** used as a fallback.\n> If an `obj_id` does not exist in the target environment, that item\n> fails with `UNRESOLVED_SOURCE`. Remove or correct stale `obj_id`\n> values before importing across environments.\n\n#### Validations reference\n\nThe payload is fully validated before anything is written. This applies to `dry_run = true` and `dry_run = false` alike: if any item fails validation, the entire import is rejected — no partial writes — and all failures are returned together so you can fix them in one pass.\n\n##### Limits\n\nDefault limits (may be adjusted in future if the need arises):\n\n| Limit | Default |\n|-------|---------|\n| Uploaded file size | 10 MiB |\n| Total memory items | 10,000 |\n| `rule_definition` length | 1,000 characters |\n| `user_query` length | 1,000 characters |\n| `recipe` length | 2,000 characters |\n| `rules` combined length (`ALWAYS_APPLY_RULES`) | 2,000 characters |\n| Tags per item | 10 |\n| Characters per tag | 50 |\n\nThe `rules` limit in `ALWAYS_APPLY_RULES` is a combined budget across all entries in the list, not per entry.\n\n##### Structural rules\n\n- The document must be a mapping with a `memories` key whose value is a list.\n- Unknown keys — at the top level, within an item, or under `content` — are rejected.\n- Each item's `type` must be one of the three supported values, and `content` must match that type's shape.\n- Null, empty-string, or wrong-typed values in a required field are treated as missing.\n- Non-string or empty `tags` entries are dropped silently; certain tags reserved for internal use are stripped automatically before the item is stored.\n\n##### Cross-item rules\n\n- A data-model referenced by more than one `ALWAYS_APPLY_RULES` item is rejected — combine them into a single item's `rules` list.\n\n##### Failure reasons\n\nEach entry in `validation_failures` carries one of:\n\n| Reason | Meaning |\n|--------|---------|\n| `SCHEMA` | YAML structure is invalid or unsupported. |\n| `VALIDATION` | A required field is missing/empty, a count exceeds a limit, or a GUID is malformed. |\n| `CHAR_LIMIT` | A content field or tag exceeds its size limit. |\n| `UNRESOLVED_SOURCE` | A `guid` or `obj_id` could not be resolved to an existing data-model. |\n| `ACCESS_DENIED` | The caller lacks sufficient access on the referenced data-model. |\n\n#### Dry run\n\n`dry_run` is required and has no default, so the import is always a deliberate two-step flow:\n\n1. **First, call with `dry_run = true`.** This validates the payload and previews what would happen — the counts in `summary` and any `validation_failures` — without writing anything.\n2. **Then, after reviewing a clean preview, call again with `dry_run = false`** (same `content`). This applies the import. It refuses to write when any item fails validation, so fix the reported `validation_failures` and resubmit.\n\n> ###### Important:\n> Never call `dry_run = false` without first inspecting a `dry_run = true` preview. A real import deletes and replaces existing global memories on the referenced data-models.\n\n#### Error responses\n\n| Code | Description |\n|------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| 401 | Unauthorized — authentication token is missing, expired, or invalid. |\n| 403 | Forbidden — the authenticated user does not have the necessary Spotter permissions, or the bearer token does not correspond to the data-model's org. Per-data-model access failures do not use this code — they surface as `ACCESS_DENIED` validation failures with HTTP `200` (see Logical failures below). |\n\n#### Logical failures\n\nValidation and write failures are not returned in the error envelope. The call returns `200` with a terminal `status` of `VALIDATION_FAILED` or `FAILED`, and the details live in `validation_failures` / `diagnostics`:\n\n- **VALIDATION_FAILED** — one or more items failed schema/semantic validation; nothing was written. Inspect `validation_failures`, fix the items, and resubmit.\n- **FAILED** — the import did not complete. Inspect `diagnostics`: a `ROLLED_BACK` group means writing the new entries failed and any entries written before the failure were undone (existing memory is intact, no destructive change), while a `FAILURE` group carries another non-validation cause.\n\nSample `VALIDATION_FAILED` responses (HTTP 200):\n\n**Invalid data-model (unresolved source):**\n\n```json\n{\n \"status\": \"VALIDATION_FAILED\",\n \"summary\": null,\n \"validation_failures\": [\n {\n \"line_number\": 2,\n \"reason\": \"UNRESOLVED_SOURCE\",\n \"field_name\": \"datamodel_sources[0].guid\",\n \"message\": \"unknown datamodel guid: 55555555-5555-5555-5555-555555555555\"\n }\n ],\n \"diagnostics\": [\n {\n \"sub_status\": \"FAILURE\",\n \"messages\": [\n \"unknown datamodel guid: 55555555-5555-5555-5555-555555555555\"\n ]\n }\n ],\n \"operation_id\": null\n}\n```\n\n**Inaccessible data-models:**\n\n```json\n{\n \"status\": \"VALIDATION_FAILED\",\n \"summary\": null,\n \"validation_failures\": [\n {\n \"line_number\": 2,\n \"reason\": \"ACCESS_DENIED\",\n \"field_name\": \"datamodel_sources[0]\",\n \"message\": \"Insufficient permissions on datamodel '44444444-4444-4444-4444-444444444444'\"\n },\n {\n \"line_number\": 8,\n \"reason\": \"ACCESS_DENIED\",\n \"field_name\": \"datamodel_sources[0]\",\n \"message\": \"Insufficient permissions on datamodel '33333333-3333-3333-3333-333333333333'\"\n }\n ],\n \"diagnostics\": [\n {\n \"sub_status\": \"FAILURE\",\n \"messages\": [\n \"Memory import validation failed with 2 error(s): Insufficient permissions on datamodel '44444444-4444-4444-4444-444444444444'; Insufficient permissions on datamodel '33333333-3333-3333-3333-333333333333'\"\n ]\n }\n ],\n \"operation_id\": null\n}\n```\n\n**Character-limit validations:**\n\n```json\n{\n \"status\": \"VALIDATION_FAILED\",\n \"summary\": [],\n
# --- truncated at 32 KB (64 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/thoughtspot/refs/heads/main/openapi/thoughtspot-26-8-0-cl-api-openapi.yml