Sync content types for external data
With custom content sources, you can add custom data to Optimizely Graph and query using the GraphQL API.
Optimizely Graph provides endpoints to let you define the GraphQL schema of your content source. The schema is important for the data you upload to the Optimizely Graph service.
ImportantThis feature is not enabled by default for your account. Contact Optimizely with a request to get additional sources.
Before you begin
Be aware of the following constraints:
- Content type names must be unique across all sources.
- External content types must not conflict with CMS content types.
- Synchronizing a full content definition replaces the entire schema for the source.
For API details, see the Full content type update API reference.
Synchronize full content definition
Use the full content type endpoint to upload a complete schema definition for a content source. This operation creates or replaces the schema associated with the specified source ID.
NoteThe schema does not work if several content types have the same name across sources. You must have unique names on the content types from external sources that do not conflict with content types in CMS.
The full content type API endpoint lets you sync the full definition of your content to the service.
curl --request PUT \
'https://dev.cg.optimizely.com/api/content/v3/types?id=src2' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic <Base64(AppKey:Secret)>' \
--data '{
"languages": ["en"],
"contentTypes": {
"test": {
"contentType": [],
"properties": {
"Name": {
"type": "String"
}
}
}
}
}'
var client = new HttpClient();
var request = new HttpRequestMessage(
HttpMethod.Put,
"https://dev.cg.optimizely.com/api/content/v3/types?id=src2"
);
request.Headers.Add("Authorization", "Basic <Base64(AppKey:Secret)>");
request.Content = new StringContent(
@"{
""languages"": [""en""],
""contentTypes"": {
""test"": {
""contentType"": [],
""properties"": {
""Name"": { ""type"": ""String"" }
}
}
}
}",
Encoding.UTF8,
"application/json"
);
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
id=src2– Source name, max 4 characterslanguages– Required and not empty.contentTypes– Required and not empty.test– Content type name.contentType– Required.properties– Required and not empty.
The above request creates a src2 datasource and a GraphQL schema that matches the content type.
ImportantIf you upload a full content definition using the
full content typeAPI endpoint, all data in the content source is deleted.
Example: Define a product catalog schema
The following example demonstrates how to define property types, languages, and content types for a content source that contains product information. It shows the use of simple data types in addition to the ProductLanguage property type.
{
"propertyTypes": {
"ProductLanguage": {
"properties": {
"DisplayName": {
"name": "DisplayName",
"type": "String"
},
"Name": {
"name": "Name",
"type": "String"
}
}
}
},
"label": "Commerce",
"languages": [
"en"
],
"contentTypes": {
"Catalog": {
"abstract": true,
"contentType": [],
"properties": {
"Id": {
"type": "String"
},
"Name": {
"type": "String"
}
}
},
"Product": {
"contentType": [
"Catalog"
],
"properties": {
"Id": {
"type": "String"
},
"Name": {
"type": "String"
},
"Language":{
"type": "ProductLanguage"
},
"Quantity": {
"type": "Int"
},
"Size": {
"type": "Float"
},
"Color": {
"type": "String"
}
}
}
}
}The following curl command issues a PUT request with the definition using the ID com, which is the name of the content source. If the content source does not exist already, it is created.
ImportantIf you create more content sources than your account lets you, the call will fail, and the content source will not be created.
curl --location --request PUT 'https://cg.optimizely.com/api/content/v3/types?id=com' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic V25KQmNtUlpSNTFYaDJuSmE1UWV5eEkwWWxOUVpFdWsxMDRWV1BYZkcydlcxZUluOkYwaWRhcDRPQ1ZOc0JSQTJmdVpCVDNtYXVoaVl1QWtRcDM5SHduazB2dW1XblpoZytjbmg4QnpHVU5VQlVIYTM=' \
--data '{
"propertyTypes": {
"ProductLanguage": {
"properties": {
"DisplayName": {
"name": "DisplayName",
"type": "String"
},
"Name": {
"name": "Name",
"type": "String"
}
}
}
},
"label": "Commerce",
"languages": [
"sv"
],
"contentTypes": {
"Catalog": {
"abstract": true,
"contentType": [],
"properties": {
"Id": {
"type": "String"
},
"Name": {
"type": "String"
}
}
},
"Product": {
"contentType": [
"Catalog"
],
"properties": {
"Id": {
"type": "String"
},
"Name": {
"type": "String"
},
"Language":{
"type": "ProductLanguage"
},
"Quantity": {
"type": "Int"
},
"Size": {
"type": "Float"
},
"Color": {
"type": "String"
}
}
}
}
}'Authorization
The acceptable authorization is Basic and epi-hmac:
Basic:
- Username – AppKey
- Password – Secret
Both the username and password must be encoded by the base64 algorithm, so the header is Authorization: Basic base64(AppKey:Secret).
epi-hmac – The AppKey and the Secret are signed by the hmac algorithm.
var crypto = require("crypto-js");
var sdk = require('postman-collection');
// This script uses 2 variables.
//
// EPTSKey
// EPTSSecret
//
var method = pm.request.method;
var key = pm.variables.get("EPTSKey");
var secret = CryptoJS.enc.Base64.parse(pm.variables.get("EPTSSecret"));
var target = new sdk.Url(request.url).getPathWithQuery();
var timestamp = (new Date()).getTime();
var nonce = Math.random().toString(36).substring(7);
var body = "";
if( pm.request.body )
{
body = pm.request.body.raw;
}
var bodybase64 = crypto.MD5(body).toString(CryptoJS.enc.Base64);
var hmac = crypto.HmacSHA256(key + method + target + timestamp + nonce + bodybase64, secret);
var base64hmac = CryptoJS.enc.Base64.stringify(hmac);
var header = "epi-hmac " + key + ":" + timestamp +":" + nonce + ":" + base64hmac;
pm.request.headers.add(header, "Authorization")
Sync partial content type
The Partial content type endpoint lets you sync the partial content type to the service.
NoteRefer to the API Reference on Partial content type update for information.
You must call synchronize full content type before using this endpoint to update partial content type.
Example: Make a field searchable
The following example updates the Product content type by marking the Name property as searchable:
{
"languages": [
"en"
],
"contentTypes": {
"Product": {
"contentType": [
"Catalog"
],
"properties": {
"Id": {
"type": "String"
},
"Name": {
"type": "String",
"searchable": true
},
"Language":{
"type": "ProductLanguage"
},
"Quantity": {
"type": "Int"
},
"Size": {
"type": "Float"
},
"Color": {
"type": "String"
}
}
}
}
}Again, the data is being sent to the types endpoint but using POST instead of PUT. It uses the com ID to specify the target content source.
curl --location 'https://cg.optimizely.com/api/content/v3/types?id=com' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic V25KQmNtUlpSNTFYaDJuSmE1UWV5eEkwWWxOUVpFdWsxMDRWV1BYZkcydlcxZUluOkYwaWRhcDRPQ1ZOc0JSQTJmdVpCVDNtYXVoaVl1QWtRcDM5SHduazB2dW1XblpoZytjbmg4QnpHVU5VQlVIYTM=' \
--data '{
"languages": [
"en"
],
"contentTypes": {
"Product": {
"contentType": [
"Catalog"
],
"properties": {
"Id": {
"type": "String"
},
"Name": {
"type": "String",
"searchable": true
},
"Language":{
"type": "ProductLanguage"
},
"Quantity": {
"type": "Int"
},
"Size": {
"type": "Float"
},
"Color": {
"type": "String"
}
}
}
}
}'Updated 15 days ago
