curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datamartName": "sales-analytics",
"tables": [
{
"name": "orders",
"description": "Customer purchase orders",
"synonyms": ["purchases", "transactions"],
"columns": [
{
"name": "order_id",
"description": "Unique order identifier",
"columnType": "Identifier",
"isIdentifier": true
},
{
"name": "status",
"description": "Current order status",
"synonyms": ["order status", "state"],
"columnType": "ENUM"
},
{
"name": "amount",
"description": "Total order amount in USD",
"columnType": "Number"
}
]
}
],
"feedback": "This datamart covers e-commerce sales data. All amounts are in USD."
}'
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datamartName": "sales-analytics",
"feedback": "This datamart covers e-commerce sales data. Fiscal year starts April 1."
}'
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
datamartName: 'sales-analytics',
tables: [
{
name: 'orders',
description: 'Customer purchase orders',
synonyms: ['purchases', 'transactions'],
columns: [
{
name: 'order_id',
description: 'Unique order identifier',
columnType: 'Identifier',
isIdentifier: true
},
{
name: 'amount',
description: 'Total order amount in USD',
columnType: 'Number'
}
]
}
],
feedback: 'All amounts are in USD.'
})
});
const result = await response.json();
if (result.error) {
console.error('Create failed:', result.error.message);
} else {
console.log('Semantic layer created for:', result.id);
}
import requests
response = requests.post(
'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer',
headers={
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
json={
'datamartName': 'sales-analytics',
'tables': [
{
'name': 'orders',
'description': 'Customer purchase orders',
'synonyms': ['purchases', 'transactions'],
'columns': [
{
'name': 'order_id',
'description': 'Unique order identifier',
'columnType': 'Identifier',
'isIdentifier': True
},
{
'name': 'amount',
'description': 'Total order amount in USD',
'columnType': 'Number'
}
]
}
],
'feedback': 'All amounts are in USD.'
}
)
result = response.json()
if result.get('error'):
print(f"Create failed: {result['error']['message']}")
else:
print(f"Semantic layer created for: {result['id']}")
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
request['Content-Type'] = 'application/json'
request.body = {
datamartName: 'sales-analytics',
tables: [
{
name: 'orders',
description: 'Customer purchase orders',
columns: [
{ name: 'order_id', description: 'Unique order identifier', columnType: 'Identifier' },
{ name: 'amount', description: 'Total order amount', columnType: 'Number' }
]
}
],
feedback: 'All amounts are in USD.'
}.to_json
response = http.request(request)
result = JSON.parse(response.body)
puts "Created: #{result['id']}"
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class CreateSemanticLayer {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String requestBody = """
{
"datamartName": "sales-analytics",
"tables": [
{
"name": "orders",
"description": "Customer purchase orders",
"columns": [
{
"name": "order_id",
"description": "Unique order identifier",
"columnType": "Identifier",
"isIdentifier": true
},
{
"name": "amount",
"description": "Total order amount in USD",
"columnType": "Number"
}
]
}
],
"feedback": "All amounts are in USD."
}""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer"))
.header("Authorization", "Bearer dbn_live_abc123...")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
body := map[string]interface{}{
"datamartName": "sales-analytics",
"tables": []map[string]interface{}{
{
"name": "orders",
"description": "Customer purchase orders",
"columns": []map[string]interface{}{
{
"name": "order_id",
"description": "Unique order identifier",
"columnType": "Identifier",
"isIdentifier": true,
},
{
"name": "amount",
"description": "Total order amount in USD",
"columnType": "Number",
},
},
},
},
"feedback": "All amounts are in USD.",
}
jsonData, _ := json.Marshal(body)
req, _ := http.NewRequest("POST",
"https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer",
bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
fmt.Println("Semantic layer created")
}
<?php
$url = 'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer';
$data = [
'datamartName' => 'sales-analytics',
'tables' => [
[
'name' => 'orders',
'description' => 'Customer purchase orders',
'columns' => [
[
'name' => 'order_id',
'description' => 'Unique order identifier',
'columnType' => 'Identifier',
'isIdentifier' => true
],
[
'name' => 'amount',
'description' => 'Total order amount in USD',
'columnType' => 'Number'
]
]
]
],
'feedback' => 'All amounts are in USD.'
];
$options = [
'http' => [
'header' => [
'Authorization: Bearer dbn_live_abc123...',
'Content-Type: application/json'
],
'method' => 'POST',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$result = json_decode($response, true);
echo "Created: " . $result['id'];
?>
{
"id": "sales-analytics"
}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"datamartName\" is required"
}
}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"value\" must contain at least one of [tables, feedback]"
}
}
{
"error": {
"code": "INVALID_TABLE",
"message": "Table 'nonexistent_table' not found in datamart 'sales-analytics'"
}
}
{
"error": {
"code": "INVALID_COLUMN",
"message": "Column 'nonexistent_col' not found in table 'orders'"
}
}
{
"error": {
"code": "INVALID_COLUMN_TYPE",
"message": "Column type 'Number' is not compatible with datatype 'varchar' for column 'status' in table 'orders'"
}
}
{
"error": {
"code": "DUPLICATE_SYNONYM",
"message": "Duplicate synonyms for table 'orders': purchases"
}
}
{
"error": {
"code": "SEMANTIC_LAYER_ALREADY_EXISTS",
"message": "Semantic layer already exists for datamart 'sales-analytics'. Use PUT to update."
}
}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "Semantic Layer API requires a service token, not a data app API token"
}
}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datamartName": "sales-analytics",
"tables": [
{
"name": "orders",
"description": "Customer purchase orders",
"synonyms": ["purchases", "transactions"],
"columns": [
{
"name": "order_id",
"description": "Unique order identifier",
"columnType": "Identifier",
"isIdentifier": true
},
{
"name": "status",
"description": "Current order status",
"synonyms": ["order status", "state"],
"columnType": "ENUM"
},
{
"name": "amount",
"description": "Total order amount in USD",
"columnType": "Number"
}
]
}
],
"feedback": "This datamart covers e-commerce sales data. All amounts are in USD."
}'
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datamartName": "sales-analytics",
"feedback": "This datamart covers e-commerce sales data. Fiscal year starts April 1."
}'
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
datamartName: 'sales-analytics',
tables: [
{
name: 'orders',
description: 'Customer purchase orders',
synonyms: ['purchases', 'transactions'],
columns: [
{
name: 'order_id',
description: 'Unique order identifier',
columnType: 'Identifier',
isIdentifier: true
},
{
name: 'amount',
description: 'Total order amount in USD',
columnType: 'Number'
}
]
}
],
feedback: 'All amounts are in USD.'
})
});
const result = await response.json();
if (result.error) {
console.error('Create failed:', result.error.message);
} else {
console.log('Semantic layer created for:', result.id);
}
import requests
response = requests.post(
'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer',
headers={
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
json={
'datamartName': 'sales-analytics',
'tables': [
{
'name': 'orders',
'description': 'Customer purchase orders',
'synonyms': ['purchases', 'transactions'],
'columns': [
{
'name': 'order_id',
'description': 'Unique order identifier',
'columnType': 'Identifier',
'isIdentifier': True
},
{
'name': 'amount',
'description': 'Total order amount in USD',
'columnType': 'Number'
}
]
}
],
'feedback': 'All amounts are in USD.'
}
)
result = response.json()
if result.get('error'):
print(f"Create failed: {result['error']['message']}")
else:
print(f"Semantic layer created for: {result['id']}")
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
request['Content-Type'] = 'application/json'
request.body = {
datamartName: 'sales-analytics',
tables: [
{
name: 'orders',
description: 'Customer purchase orders',
columns: [
{ name: 'order_id', description: 'Unique order identifier', columnType: 'Identifier' },
{ name: 'amount', description: 'Total order amount', columnType: 'Number' }
]
}
],
feedback: 'All amounts are in USD.'
}.to_json
response = http.request(request)
result = JSON.parse(response.body)
puts "Created: #{result['id']}"
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class CreateSemanticLayer {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String requestBody = """
{
"datamartName": "sales-analytics",
"tables": [
{
"name": "orders",
"description": "Customer purchase orders",
"columns": [
{
"name": "order_id",
"description": "Unique order identifier",
"columnType": "Identifier",
"isIdentifier": true
},
{
"name": "amount",
"description": "Total order amount in USD",
"columnType": "Number"
}
]
}
],
"feedback": "All amounts are in USD."
}""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer"))
.header("Authorization", "Bearer dbn_live_abc123...")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
body := map[string]interface{}{
"datamartName": "sales-analytics",
"tables": []map[string]interface{}{
{
"name": "orders",
"description": "Customer purchase orders",
"columns": []map[string]interface{}{
{
"name": "order_id",
"description": "Unique order identifier",
"columnType": "Identifier",
"isIdentifier": true,
},
{
"name": "amount",
"description": "Total order amount in USD",
"columnType": "Number",
},
},
},
},
"feedback": "All amounts are in USD.",
}
jsonData, _ := json.Marshal(body)
req, _ := http.NewRequest("POST",
"https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer",
bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
fmt.Println("Semantic layer created")
}
<?php
$url = 'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer';
$data = [
'datamartName' => 'sales-analytics',
'tables' => [
[
'name' => 'orders',
'description' => 'Customer purchase orders',
'columns' => [
[
'name' => 'order_id',
'description' => 'Unique order identifier',
'columnType' => 'Identifier',
'isIdentifier' => true
],
[
'name' => 'amount',
'description' => 'Total order amount in USD',
'columnType' => 'Number'
]
]
]
],
'feedback' => 'All amounts are in USD.'
];
$options = [
'http' => [
'header' => [
'Authorization: Bearer dbn_live_abc123...',
'Content-Type: application/json'
],
'method' => 'POST',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$result = json_decode($response, true);
echo "Created: " . $result['id'];
?>
{
"id": "sales-analytics"
}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"datamartName\" is required"
}
}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"value\" must contain at least one of [tables, feedback]"
}
}
{
"error": {
"code": "INVALID_TABLE",
"message": "Table 'nonexistent_table' not found in datamart 'sales-analytics'"
}
}
{
"error": {
"code": "INVALID_COLUMN",
"message": "Column 'nonexistent_col' not found in table 'orders'"
}
}
{
"error": {
"code": "INVALID_COLUMN_TYPE",
"message": "Column type 'Number' is not compatible with datatype 'varchar' for column 'status' in table 'orders'"
}
}
{
"error": {
"code": "DUPLICATE_SYNONYM",
"message": "Duplicate synonyms for table 'orders': purchases"
}
}
{
"error": {
"code": "SEMANTIC_LAYER_ALREADY_EXISTS",
"message": "Semantic layer already exists for datamart 'sales-analytics'. Use PUT to update."
}
}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "Semantic Layer API requires a service token, not a data app API token"
}
}
Semantic Layer APIs
Create Semantic Layer
Create a semantic layer for a datamart by adding table descriptions, column metadata, and feedback.
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datamartName": "sales-analytics",
"tables": [
{
"name": "orders",
"description": "Customer purchase orders",
"synonyms": ["purchases", "transactions"],
"columns": [
{
"name": "order_id",
"description": "Unique order identifier",
"columnType": "Identifier",
"isIdentifier": true
},
{
"name": "status",
"description": "Current order status",
"synonyms": ["order status", "state"],
"columnType": "ENUM"
},
{
"name": "amount",
"description": "Total order amount in USD",
"columnType": "Number"
}
]
}
],
"feedback": "This datamart covers e-commerce sales data. All amounts are in USD."
}'
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datamartName": "sales-analytics",
"feedback": "This datamart covers e-commerce sales data. Fiscal year starts April 1."
}'
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
datamartName: 'sales-analytics',
tables: [
{
name: 'orders',
description: 'Customer purchase orders',
synonyms: ['purchases', 'transactions'],
columns: [
{
name: 'order_id',
description: 'Unique order identifier',
columnType: 'Identifier',
isIdentifier: true
},
{
name: 'amount',
description: 'Total order amount in USD',
columnType: 'Number'
}
]
}
],
feedback: 'All amounts are in USD.'
})
});
const result = await response.json();
if (result.error) {
console.error('Create failed:', result.error.message);
} else {
console.log('Semantic layer created for:', result.id);
}
import requests
response = requests.post(
'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer',
headers={
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
json={
'datamartName': 'sales-analytics',
'tables': [
{
'name': 'orders',
'description': 'Customer purchase orders',
'synonyms': ['purchases', 'transactions'],
'columns': [
{
'name': 'order_id',
'description': 'Unique order identifier',
'columnType': 'Identifier',
'isIdentifier': True
},
{
'name': 'amount',
'description': 'Total order amount in USD',
'columnType': 'Number'
}
]
}
],
'feedback': 'All amounts are in USD.'
}
)
result = response.json()
if result.get('error'):
print(f"Create failed: {result['error']['message']}")
else:
print(f"Semantic layer created for: {result['id']}")
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
request['Content-Type'] = 'application/json'
request.body = {
datamartName: 'sales-analytics',
tables: [
{
name: 'orders',
description: 'Customer purchase orders',
columns: [
{ name: 'order_id', description: 'Unique order identifier', columnType: 'Identifier' },
{ name: 'amount', description: 'Total order amount', columnType: 'Number' }
]
}
],
feedback: 'All amounts are in USD.'
}.to_json
response = http.request(request)
result = JSON.parse(response.body)
puts "Created: #{result['id']}"
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class CreateSemanticLayer {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String requestBody = """
{
"datamartName": "sales-analytics",
"tables": [
{
"name": "orders",
"description": "Customer purchase orders",
"columns": [
{
"name": "order_id",
"description": "Unique order identifier",
"columnType": "Identifier",
"isIdentifier": true
},
{
"name": "amount",
"description": "Total order amount in USD",
"columnType": "Number"
}
]
}
],
"feedback": "All amounts are in USD."
}""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer"))
.header("Authorization", "Bearer dbn_live_abc123...")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
body := map[string]interface{}{
"datamartName": "sales-analytics",
"tables": []map[string]interface{}{
{
"name": "orders",
"description": "Customer purchase orders",
"columns": []map[string]interface{}{
{
"name": "order_id",
"description": "Unique order identifier",
"columnType": "Identifier",
"isIdentifier": true,
},
{
"name": "amount",
"description": "Total order amount in USD",
"columnType": "Number",
},
},
},
},
"feedback": "All amounts are in USD.",
}
jsonData, _ := json.Marshal(body)
req, _ := http.NewRequest("POST",
"https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer",
bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
fmt.Println("Semantic layer created")
}
<?php
$url = 'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer';
$data = [
'datamartName' => 'sales-analytics',
'tables' => [
[
'name' => 'orders',
'description' => 'Customer purchase orders',
'columns' => [
[
'name' => 'order_id',
'description' => 'Unique order identifier',
'columnType' => 'Identifier',
'isIdentifier' => true
],
[
'name' => 'amount',
'description' => 'Total order amount in USD',
'columnType' => 'Number'
]
]
]
],
'feedback' => 'All amounts are in USD.'
];
$options = [
'http' => [
'header' => [
'Authorization: Bearer dbn_live_abc123...',
'Content-Type: application/json'
],
'method' => 'POST',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$result = json_decode($response, true);
echo "Created: " . $result['id'];
?>
{
"id": "sales-analytics"
}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"datamartName\" is required"
}
}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"value\" must contain at least one of [tables, feedback]"
}
}
{
"error": {
"code": "INVALID_TABLE",
"message": "Table 'nonexistent_table' not found in datamart 'sales-analytics'"
}
}
{
"error": {
"code": "INVALID_COLUMN",
"message": "Column 'nonexistent_col' not found in table 'orders'"
}
}
{
"error": {
"code": "INVALID_COLUMN_TYPE",
"message": "Column type 'Number' is not compatible with datatype 'varchar' for column 'status' in table 'orders'"
}
}
{
"error": {
"code": "DUPLICATE_SYNONYM",
"message": "Duplicate synonyms for table 'orders': purchases"
}
}
{
"error": {
"code": "SEMANTIC_LAYER_ALREADY_EXISTS",
"message": "Semantic layer already exists for datamart 'sales-analytics'. Use PUT to update."
}
}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "Semantic Layer API requires a service token, not a data app API token"
}
}
POST
/
api
/
v2
/
data-app
/
datamarts
/
semantic-layer
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datamartName": "sales-analytics",
"tables": [
{
"name": "orders",
"description": "Customer purchase orders",
"synonyms": ["purchases", "transactions"],
"columns": [
{
"name": "order_id",
"description": "Unique order identifier",
"columnType": "Identifier",
"isIdentifier": true
},
{
"name": "status",
"description": "Current order status",
"synonyms": ["order status", "state"],
"columnType": "ENUM"
},
{
"name": "amount",
"description": "Total order amount in USD",
"columnType": "Number"
}
]
}
],
"feedback": "This datamart covers e-commerce sales data. All amounts are in USD."
}'
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datamartName": "sales-analytics",
"feedback": "This datamart covers e-commerce sales data. Fiscal year starts April 1."
}'
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
datamartName: 'sales-analytics',
tables: [
{
name: 'orders',
description: 'Customer purchase orders',
synonyms: ['purchases', 'transactions'],
columns: [
{
name: 'order_id',
description: 'Unique order identifier',
columnType: 'Identifier',
isIdentifier: true
},
{
name: 'amount',
description: 'Total order amount in USD',
columnType: 'Number'
}
]
}
],
feedback: 'All amounts are in USD.'
})
});
const result = await response.json();
if (result.error) {
console.error('Create failed:', result.error.message);
} else {
console.log('Semantic layer created for:', result.id);
}
import requests
response = requests.post(
'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer',
headers={
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
json={
'datamartName': 'sales-analytics',
'tables': [
{
'name': 'orders',
'description': 'Customer purchase orders',
'synonyms': ['purchases', 'transactions'],
'columns': [
{
'name': 'order_id',
'description': 'Unique order identifier',
'columnType': 'Identifier',
'isIdentifier': True
},
{
'name': 'amount',
'description': 'Total order amount in USD',
'columnType': 'Number'
}
]
}
],
'feedback': 'All amounts are in USD.'
}
)
result = response.json()
if result.get('error'):
print(f"Create failed: {result['error']['message']}")
else:
print(f"Semantic layer created for: {result['id']}")
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
request['Content-Type'] = 'application/json'
request.body = {
datamartName: 'sales-analytics',
tables: [
{
name: 'orders',
description: 'Customer purchase orders',
columns: [
{ name: 'order_id', description: 'Unique order identifier', columnType: 'Identifier' },
{ name: 'amount', description: 'Total order amount', columnType: 'Number' }
]
}
],
feedback: 'All amounts are in USD.'
}.to_json
response = http.request(request)
result = JSON.parse(response.body)
puts "Created: #{result['id']}"
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class CreateSemanticLayer {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String requestBody = """
{
"datamartName": "sales-analytics",
"tables": [
{
"name": "orders",
"description": "Customer purchase orders",
"columns": [
{
"name": "order_id",
"description": "Unique order identifier",
"columnType": "Identifier",
"isIdentifier": true
},
{
"name": "amount",
"description": "Total order amount in USD",
"columnType": "Number"
}
]
}
],
"feedback": "All amounts are in USD."
}""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer"))
.header("Authorization", "Bearer dbn_live_abc123...")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
body := map[string]interface{}{
"datamartName": "sales-analytics",
"tables": []map[string]interface{}{
{
"name": "orders",
"description": "Customer purchase orders",
"columns": []map[string]interface{}{
{
"name": "order_id",
"description": "Unique order identifier",
"columnType": "Identifier",
"isIdentifier": true,
},
{
"name": "amount",
"description": "Total order amount in USD",
"columnType": "Number",
},
},
},
},
"feedback": "All amounts are in USD.",
}
jsonData, _ := json.Marshal(body)
req, _ := http.NewRequest("POST",
"https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer",
bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
fmt.Println("Semantic layer created")
}
<?php
$url = 'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer';
$data = [
'datamartName' => 'sales-analytics',
'tables' => [
[
'name' => 'orders',
'description' => 'Customer purchase orders',
'columns' => [
[
'name' => 'order_id',
'description' => 'Unique order identifier',
'columnType' => 'Identifier',
'isIdentifier' => true
],
[
'name' => 'amount',
'description' => 'Total order amount in USD',
'columnType' => 'Number'
]
]
]
],
'feedback' => 'All amounts are in USD.'
];
$options = [
'http' => [
'header' => [
'Authorization: Bearer dbn_live_abc123...',
'Content-Type: application/json'
],
'method' => 'POST',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$result = json_decode($response, true);
echo "Created: " . $result['id'];
?>
{
"id": "sales-analytics"
}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"datamartName\" is required"
}
}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"value\" must contain at least one of [tables, feedback]"
}
}
{
"error": {
"code": "INVALID_TABLE",
"message": "Table 'nonexistent_table' not found in datamart 'sales-analytics'"
}
}
{
"error": {
"code": "INVALID_COLUMN",
"message": "Column 'nonexistent_col' not found in table 'orders'"
}
}
{
"error": {
"code": "INVALID_COLUMN_TYPE",
"message": "Column type 'Number' is not compatible with datatype 'varchar' for column 'status' in table 'orders'"
}
}
{
"error": {
"code": "DUPLICATE_SYNONYM",
"message": "Duplicate synonyms for table 'orders': purchases"
}
}
{
"error": {
"code": "SEMANTIC_LAYER_ALREADY_EXISTS",
"message": "Semantic layer already exists for datamart 'sales-analytics'. Use PUT to update."
}
}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "Semantic Layer API requires a service token, not a data app API token"
}
}
Add semantic metadata to a datamart that doesn’t have a semantic layer yet. This includes table and column descriptions, synonyms, column type classifications, and global feedback for AI context.
This endpoint will reject the request with
409 SEMANTIC_LAYER_ALREADY_EXISTS if the datamart already has semantic data. Use PUT to modify an existing semantic layer.At least one of
tables or feedback must be provided in the request body.Authentication
This endpoint requires a service token in the Authorization header. Data app API tokens are not permitted and will be rejected with a403 error.
To access your service token:
- Go to your Databrain dashboard and open Settings.
- Navigate to Settings.
- Find the Service Tokens section.
- Click the “Generate Token” button to generate a new service token if you don’t have one already.
Headers
string
required
Bearer token for API authentication. Use your service token.
Authorization: Bearer dbn_live_abc123...
string
required
Must be set to
application/json for all requests.Content-Type: application/json
Request Body
string
required
Name of the existing datamart to create a semantic layer for. Must match exactly (case-sensitive).
Show Finding datamart names
Show Finding datamart names
- Use the List Datamarts API to get all datamart names
- Names are case-sensitive and must match exactly
- The datamart must not already have semantic data
array
Array of table objects with semantic metadata. Each table must reference a table that exists in the datamart.
Show Validation rules
Show Validation rules
- Table
namemust match an existing table in the datamart - Column
name(when provided) must match an existing column in the respective table - Descriptions are limited to 500 characters
- Synonyms are limited to 10 per entity, 100 characters each
- Synonyms must be unique (case-insensitive)
string
required
Table name from the datamart. Must match an existing table.
string
Optional schema name for the table.
string
Human-readable description of the table. Maximum 500 characters.
string[]
Alternative names for the table. Maximum 10 synonyms, each up to 100 characters. Must be unique (case-insensitive).
string
Additional context for AI query generation. Maximum 1000 characters.
array
Array of column objects with semantic metadata.
string
required
Column name from the table. Must match an existing column.
string
Human-readable description of the column. Maximum 500 characters.
string[]
Alternative names for the column. Maximum 10 synonyms, each up to 100 characters. Must be unique (case-insensitive).
string
Additional context for AI query generation. Maximum 1000 characters.
string
Semantic column type classification. Must be one of:
String, Long String, String (Custom), ENUM, Mapper, Range, Expression, Identifier, Number, JSON.Show Column type compatibility
Show Column type compatibility
The column type must be compatible with the column’s underlying SQL datatype. For example,
Number cannot be assigned to a varchar column.object | string | null
Additional configuration for the column type. Must match the shape expected for
columnType:String,String (Custom),ENUM,Mapper: plain object mapping values to descriptions (e.g.{ "pending": "Not shipped", "shipped": "Sent" })Range:{ "lowerLimit": number, "upperLimit": number }(both must be numbers)Expression: string templateJSON: string (sample JSON)Identifier,Number,Long String: omit or usenull(non-null config is rejected)
Show Config validation
Show Config validation
Invalid configs return
400 INVALID_COLUMN_TYPE_CONFIG with a message describing the required shape.boolean
Mark this column as an identifier (e.g., primary key, foreign key). Defaults to
false.boolean
Exclude this column from AI indexing. Defaults to
false.string
Global feedback text providing context to the AI about this datamart. Maximum 2000 characters.
Show Feedback usage
Show Feedback usage
- Helps guide AI-generated SQL queries
- Example: “All monetary amounts are in USD. The fiscal year starts in April.”
- Can be used alone (without tables)
Response
On success, the response body contains only the datamart name. There is noerror field in the JSON body when the request succeeds.
string
The name of the datamart (same as the input
datamartName) on success.Examples
HTTP Status Code Summary
| Status Code | Description |
|---|---|
200 | OK — Semantic layer created successfully |
400 | Bad Request — Validation failed (see error codes below) |
401 | Unauthorized — Invalid or missing API token |
403 | Forbidden — Data app token used instead of service token |
409 | Conflict — Semantic layer already exists on this datamart |
500 | Internal Server Error — Server error occurred |
Possible Errors
| Error Code | HTTP Status | Description |
|---|---|---|
INVALID_REQUEST_BODY | 400 | Missing required fields or validation failure |
INVALID_DATAMART | 400 | Datamart not found |
INVALID_TABLE | 400 | Table name doesn’t exist in the datamart |
INVALID_COLUMN | 400 | Column name doesn’t exist in the table |
INVALID_COLUMN_TYPE | 400 | Column type incompatible with the column’s datatype |
INVALID_COLUMN_TYPE_CONFIG | 400 | Column type config has wrong shape for the column type |
DUPLICATE_SYNONYM | 400 | Duplicate synonyms detected (case-insensitive) |
SEMANTIC_LAYER_ALREADY_EXISTS | 409 | Datamart already has semantic data — use PUT to update |
AUTHENTICATION_ERROR | 403 | Data app token used instead of service token |
INTERNAL_SERVER_ERROR | 500 | Server error |
Quick Start Guide
1
Verify your datamart exists
Use the List Datamarts API to confirm the datamart exists and note its exact name.
2
Prepare your semantic metadata
Gather descriptions, synonyms, and column type classifications for your tables:
{
"datamartName": "sales-analytics",
"tables": [
{
"name": "orders",
"description": "Customer purchase orders",
"synonyms": ["purchases"],
"columns": [
{ "name": "order_id", "description": "Unique identifier", "columnType": "Identifier" },
{ "name": "amount", "description": "Total in USD", "columnType": "Number" }
]
}
],
"feedback": "All monetary values are in USD."
}
3
Create the semantic layer
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{ ... }'
4
Verify with GET
Retrieve the semantic layer to confirm it was created and check the completion score:
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer?datamartName=sales-analytics' \
--header 'Authorization: Bearer dbn_live_abc123...'
Next Steps
Get Semantic Layer
Retrieve and inspect your semantic layer
Update Semantic Layer
Modify your semantic layer after creation
Delete Semantic Layer
Remove semantic layer metadata
Semantic Layer Guide
Configure the semantic layer in the Databrain UI
⌘I

