<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><language>en</language><title>Blog posts by Akash</title> <link>https://world.optimizely.com/blogs/akash/</link><description></description><ttl>60</ttl><generator>Optimizely World</generator><item> <title>Fixing index_not_found_exception After Purging External Data in Optimizely Graph</title>            <link>https://world.optimizely.com/blogs/akash/dates/2026/7/index-external-data-with-optimizely-graph/</link>            <description>&lt;h3&gt;The Scenario: Indexing External Data&lt;/h3&gt;
&lt;p&gt;When working with Optimizely Content Graph, indexing external data is a straightforward process. &lt;a href=&quot;https://docs.developers.optimizely.com/platform-optimizely/docs/sync-content-data&quot;&gt;Synchronize custom data sources with Optimizely Graph&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Followed by setting up a GraphQL schema to push an external content type called &lt;strong&gt;Article &lt;/strong&gt;into a specific source src1&lt;/p&gt;
&lt;p&gt;Here is the initial schema definition using the V3 API:&lt;/p&gt;
&lt;p&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;/p&gt;
&lt;div class=&quot;code-block ng-tns-c2171817996-27 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation&quot;&gt;&lt;!----&gt;
&lt;div class=&quot;formatted-code-block-internal-container ng-tns-c2171817996-27&quot;&gt;
&lt;div class=&quot;animated-opacity ng-tns-c2171817996-27&quot;&gt;&lt;!----&gt;
&lt;pre class=&quot;ng-tns-c2171817996-27&quot;&gt;&lt;code class=&quot;code-container formatted ng-tns-c2171817996-27&quot;&gt;curl --location --request PUT &lt;span class=&quot;hljs-string&quot;&gt;&#39;https://cg.optimizely.com/api/content/v3/types?id=src1&#39;&lt;/span&gt; \
--header &lt;span class=&quot;hljs-string&quot;&gt;&#39;Content-Type: application/json&#39;&lt;/span&gt; \
--header &lt;span class=&quot;hljs-string&quot;&gt;&#39;Authorization: Basic BASE64_ENCODED_CREDENTIALS&#39;&lt;/span&gt; \
--data &lt;span class=&quot;hljs-string&quot;&gt;&#39;{  
  &quot;languages&quot;: [&quot;en-US&quot;],
  &quot;contentTypes&quot;:{
   &quot;Article&quot;: {
     &quot;contentType&quot;: [],
     &quot;properties&quot;: {
       &quot;Id&quot;: { &quot;type&quot;: &quot;Int&quot; },
       &quot;Keywords&quot;: { &quot;type&quot;: &quot;String&quot;, &quot;searchable&quot;: true },
       &quot;Language&quot;: { &quot;type&quot;: &quot;String&quot; },
       &quot;Comment&quot;: { &quot;type&quot;: &quot;String&quot; },
       &quot;Body&quot;: { &quot;type&quot;: &quot;String&quot;, &quot;searchable&quot;: true },
       &quot;Summary&quot;: { &quot;type&quot;: &quot;String&quot;, &quot;searchable&quot;: true },
       &quot;CreatedTime&quot;: { &quot;type&quot;: &quot;Date&quot; }      
     }
   }
 } 
}&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;!----&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;/p&gt;
&lt;p&gt;After registering the schema, I successfully synced the content using Post request via a scheduled job. The data was indexed and queryable.&lt;code&gt;POST /api/content/v2/data?id=src1&lt;/code&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;The Problem: A Silent Failure Post-Purge&lt;/h3&gt;
&lt;p&gt;To clean up the index and start fresh, I executed a purge operation using the API: &lt;code&gt;DELETE /api/content/v2/data?id=src1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;While the purge succeeded and cleared the results, a major issue occurred when my scheduled job tried to sync new data. The Post request returned a successful response with a journalId, but queries still returned zero items.&lt;/p&gt;
&lt;p&gt;Upon checking the journal stream details in Postman I found the culprit: a failed status throwing an &lt;strong&gt;index_not_found_exception&lt;/strong&gt;&amp;nbsp;&lt;code&gt;https://cg.optimizely.com/journal/stream/journalId&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/12ce3b2d0ae34c59b8981d2f360438db.aspx&quot; alt=&quot;&quot; width=&quot;1065&quot; height=&quot;294&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;The Root Cause: Management Layer vs. Storage Layer&lt;/h3&gt;
&lt;p&gt;Why did the API return a success response if the index didn&#39;t exist? The answer lies in how Optimizely Content Graph separates data configuration:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The Management Layer (Schema Registry):&lt;/strong&gt; When you check for your schema, the API looks at its registry. The blueprint for &lt;strong&gt;Article&lt;/strong&gt; is still there, so the ingestion gateway assumes everything is fine and accepts your data stream (giving you a success response and a journalId).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The Storage Layer (Elasticsearch Cluster):&lt;/strong&gt; This is where the physical data buckets live. When you performed the purge, it completely wiped the physical storage bucket to free up cloud resources.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When the background worker attempts to write your new data to the physical storage layer, it panics and throws the &lt;strong&gt;index_not_found_exception &lt;/strong&gt;because the actual bucket no longer exists.&lt;/p&gt;
&lt;p&gt;According to the Optimizely development team, the legacy DELETE /api/content/v2/data and the newer DELETE /api/content/v3/sources?mode=data endpoints delete &lt;em&gt;all&lt;/em&gt; data, &lt;strong&gt;including the underlying indices&lt;/strong&gt;. Because this is an &lt;strong&gt;&lt;em&gt;external content type&lt;/em&gt;&lt;/strong&gt;, the system doesn&#39;t automatically rebuild the physical container upon receiving new data.&lt;/p&gt;
&lt;h3&gt;The Current Solution&lt;/h3&gt;
&lt;p&gt;If you expect a purge to solely remove records while keeping the underlying physical container intact, you will run into this error. As the purge inherently drops the Elasticsearch index, you must manually recreate it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;To resolve this, you must re-push your schema before indexing new documents.&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Purge the data:&lt;/strong&gt; &lt;code&gt;DELETE /api/content/v2/data?id=src1&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Recreate the Schema:&lt;/strong&gt; Resend your original PUT request to&amp;nbsp;o rebuild the physical storage index. &lt;code&gt;PUT /api/content/v3/types?id=src1&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sync the Content:&lt;/strong&gt; Execute your Post request to index the new documents.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;By pushing the schema again after every purge, you ensure the underlying Elasticsearch container is recreated and ready to accept your external content data streams.&lt;/p&gt;
&lt;h3&gt;Support the Feature Request&lt;/h3&gt;
&lt;p&gt;While the workaround above successfully resolves the issue, the ideal behavior would be for the purge operation to delete only the content records, leaving the underlying physical container and schema intact so background syncs don&#39;t fail.&lt;/p&gt;
&lt;p&gt;I have submitted a feedback request to the Optimizely support to address this behavior. If you have run into this same issue, please upvote and support the request here:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;a class=&quot;ng-star-inserted&quot; href=&quot;https://feedback.optimizely.com/forums/964785-cms-saas-content-management-system/suggestions/51482671-sync-external-content-data-purge-deletes-content-a&quot;&gt;Vote here: Sync External Content Data - Purge Deletes Content and Schema&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/akash/dates/2026/7/index-external-data-with-optimizely-graph/</guid>            <pubDate>Thu, 16 Jul 2026 08:20:17 GMT</pubDate>           <category>Blog post</category></item><item> <title>List Properties of a Optimizely Content Type programmatically</title>            <link>https://world.optimizely.com/blogs/akash/dates/2023/10/how-to-get-a-list-of-properties-of-a-content-type-defined-in-optimizely/</link>            <description>&lt;p&gt;Properties are simply fields used to create a content type in Optimizely. Lets explore how to get a list of properties of a specific content type defined in Optimizely. These properties can be simple text, rich text, images, links, etc. The blog is useful for devs aiming to map opti content type properties while migrating content.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Content&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In Optimizely CMS, the first term you will hear is content. Content is just like items in Sitecore.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Content Type&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The different types of content could be of type page, block, media, video, image, or a custom type.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IContentTypeRepository&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To get a list of all available content types defined in Optimizely CMS project, first, we will need an instance of IContentTypeRepository, as this is the primary API for accessing the repository methods.&lt;/p&gt;
&lt;p&gt;Through the content type repository instance, we can perform CRUD (Create, Read, Update and Delete) operations on content. Alternatively, if you only need read-only access, use the IContentLoader instance.&lt;/p&gt;
&lt;p&gt;var repository = ServiceLocator.Current.GetInstance&amp;lt;IContentTypeRepository&amp;gt;();&lt;/p&gt;
&lt;p&gt;The list() method lists all available content types (Block, Media, Page, Image, Video) in the repository.&lt;/p&gt;
&lt;p&gt;var contentTypeList = repository.List();&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/ed7ec1b5b07445e1a4cd4fe8ecf84675.aspx&quot; alt=&quot;&quot; width=&quot;640&quot; height=&quot;558&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Content type &lt;/strong&gt;- To get the content type of block or page type, we can filter the list by passing the content type.&lt;/p&gt;
&lt;p&gt;var pageTypes = repository.List().OfType&amp;lt;PageType&amp;gt;();&lt;/p&gt;
&lt;p&gt;var blockTypes = repository.List().OfType&amp;lt;BlockType&amp;gt;();&lt;/p&gt;
&lt;p&gt;By passing PageType as a parameter, we shall get all the content of the type page.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;img src=&quot;/link/03c822b310a2408aab198f39b8b999c6.aspx&quot; alt=&quot;&quot; /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;To get a specific content type, use the Load() method on the repository instance. The Load() methods have overloads, and we can get the specific content type by passing Id, Guid, ContentType, or Name as parameter.&lt;/p&gt;
&lt;p&gt;var contentType = repository.Load&amp;lt;LocationItemPage&amp;gt;();&lt;/p&gt;
&lt;p&gt;In solutions, which do not have a reference to the Optimizely CMS project example a razor class library project. The specific content type is not accessible, which is present in Optimizely Project. In such a scenario, we can use the Guid or Id saved in global constants file.&lt;/p&gt;
&lt;p&gt;var contentTypeById = contentTypeRepository.Load(contentTypeId);&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/3807614550aa4450b2dbf0814f573e5f.aspx&quot; alt=&quot;&quot; width=&quot;854&quot; height=&quot;447&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PropertyDefinitions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Returns a property collection containing all properties defined in a specific content type.&lt;/p&gt;
&lt;p&gt;var properties = contentType.PropertyDefinitions;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/f1f20e0a72254d4bab532b79701a0b98.aspx&quot; alt=&quot;&quot; width=&quot;745&quot; height=&quot;419&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Getting property names&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We can retrieve the properties and save them in list. we can use EditCaption property for getting display names of properties. If one needs actual property names use Name property.&lt;/p&gt;
&lt;p&gt;List Properties = new List&amp;lt;string&amp;gt;();&lt;/p&gt;
&lt;p&gt;foreach (var property in properties)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;{&lt;/p&gt;
&lt;p&gt;&amp;nbsp;string propertyName = property.EditCaption;&lt;/p&gt;
&lt;p&gt;Properties.Add(propertyName);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/98aa5751dfdc4df4bdde68d3d773d974.aspx&quot; alt=&quot;&quot; width=&quot;769&quot; height=&quot;584&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;You can further explore PropertyDefinitions class as it gives access to other properties and methods which can be of use in development.&lt;/p&gt;
&lt;p&gt;Happy Learning!&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/akash/dates/2023/10/how-to-get-a-list-of-properties-of-a-content-type-defined-in-optimizely/</guid>            <pubDate>Thu, 02 Jul 2026 08:48:45 GMT</pubDate>           <category>Blog post</category></item></channel>
</rss>