curl --request POST \
--url https://api.getmodus.com/api/v1/context/custom-items \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"kind": "entity",
"sourceId": "billing-db",
"sourceName": "Billing database",
"collectionId": "contracts",
"collectionName": "Contracts",
"externalId": "contract-123",
"name": "Acme renewal contract",
"entityType": "contract",
"description": "Enterprise renewal metadata from the internal billing system.",
"attributes": [
{
"name": "status",
"dataType": "string",
"value": {
"text": "active"
}
}
],
"topics": [
"billing",
"renewals"
]
}
'import requests
url = "https://api.getmodus.com/api/v1/context/custom-items"
payload = {
"kind": "entity",
"sourceId": "billing-db",
"sourceName": "Billing database",
"collectionId": "contracts",
"collectionName": "Contracts",
"externalId": "contract-123",
"name": "Acme renewal contract",
"entityType": "contract",
"description": "Enterprise renewal metadata from the internal billing system.",
"attributes": [
{
"name": "status",
"dataType": "string",
"value": { "text": "active" }
}
],
"topics": ["billing", "renewals"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
kind: 'entity',
sourceId: 'billing-db',
sourceName: 'Billing database',
collectionId: 'contracts',
collectionName: 'Contracts',
externalId: 'contract-123',
name: 'Acme renewal contract',
entityType: 'contract',
description: 'Enterprise renewal metadata from the internal billing system.',
attributes: [{name: 'status', dataType: 'string', value: {text: 'active'}}],
topics: ['billing', 'renewals']
})
};
fetch('https://api.getmodus.com/api/v1/context/custom-items', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.getmodus.com/api/v1/context/custom-items",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'kind' => 'entity',
'sourceId' => 'billing-db',
'sourceName' => 'Billing database',
'collectionId' => 'contracts',
'collectionName' => 'Contracts',
'externalId' => 'contract-123',
'name' => 'Acme renewal contract',
'entityType' => 'contract',
'description' => 'Enterprise renewal metadata from the internal billing system.',
'attributes' => [
[
'name' => 'status',
'dataType' => 'string',
'value' => [
'text' => 'active'
]
]
],
'topics' => [
'billing',
'renewals'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.getmodus.com/api/v1/context/custom-items"
payload := strings.NewReader("{\n \"kind\": \"entity\",\n \"sourceId\": \"billing-db\",\n \"sourceName\": \"Billing database\",\n \"collectionId\": \"contracts\",\n \"collectionName\": \"Contracts\",\n \"externalId\": \"contract-123\",\n \"name\": \"Acme renewal contract\",\n \"entityType\": \"contract\",\n \"description\": \"Enterprise renewal metadata from the internal billing system.\",\n \"attributes\": [\n {\n \"name\": \"status\",\n \"dataType\": \"string\",\n \"value\": {\n \"text\": \"active\"\n }\n }\n ],\n \"topics\": [\n \"billing\",\n \"renewals\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.getmodus.com/api/v1/context/custom-items")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"kind\": \"entity\",\n \"sourceId\": \"billing-db\",\n \"sourceName\": \"Billing database\",\n \"collectionId\": \"contracts\",\n \"collectionName\": \"Contracts\",\n \"externalId\": \"contract-123\",\n \"name\": \"Acme renewal contract\",\n \"entityType\": \"contract\",\n \"description\": \"Enterprise renewal metadata from the internal billing system.\",\n \"attributes\": [\n {\n \"name\": \"status\",\n \"dataType\": \"string\",\n \"value\": {\n \"text\": \"active\"\n }\n }\n ],\n \"topics\": [\n \"billing\",\n \"renewals\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.getmodus.com/api/v1/context/custom-items")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"kind\": \"entity\",\n \"sourceId\": \"billing-db\",\n \"sourceName\": \"Billing database\",\n \"collectionId\": \"contracts\",\n \"collectionName\": \"Contracts\",\n \"externalId\": \"contract-123\",\n \"name\": \"Acme renewal contract\",\n \"entityType\": \"contract\",\n \"description\": \"Enterprise renewal metadata from the internal billing system.\",\n \"attributes\": [\n {\n \"name\": \"status\",\n \"dataType\": \"string\",\n \"value\": {\n \"text\": \"active\"\n }\n }\n ],\n \"topics\": [\n \"billing\",\n \"renewals\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"contextItemId": "7a3f9d2c-1111-4000-a000-000000000abc",
"contextType": "custom_entity_metadata",
"dataPath": [
"billing-db",
"contracts",
"contract-123"
],
"title": "Acme renewal contract"
}{
"error": {
"code": "BAD_REQUEST",
"status": "INVALID_ARGUMENT",
"message": "Invalid value for query parameter `pageSize`.",
"requestId": "req_01HQ7K8ABCDEFGHIJKLMNOPQRS"
}
}{
"error": {
"code": "UNAUTHORIZED",
"status": "UNAUTHENTICATED",
"message": "Missing or invalid access token.",
"requestId": "req_01HQ7K8ABCDEFGHIJKLMNOPQRS"
}
}{
"error": {
"code": "FORBIDDEN",
"status": "PERMISSION_DENIED",
"message": "Missing required scope(s) for this operation.",
"requestId": "req_01HQ7K8ABCDEFGHIJKLMNOPQRS",
"info": {
"missing": [
"<required-scope>"
]
}
}
}{
"error": {
"code": "NOT_FOUND",
"status": "NOT_FOUND",
"message": "Resource not found.",
"requestId": "req_01HQ7K8ABCDEFGHIJKLMNOPQRS"
}
}{
"error": {
"code": "CONFLICT",
"status": "ALREADY_EXISTS",
"message": "A resource with that identifier already exists.",
"requestId": "req_01HQ7K8ABCDEFGHIJKLMNOPQRS"
}
}{
"error": {
"code": "VALIDATION",
"status": "INVALID_ARGUMENT",
"message": "Updates that would revoke your own access are not allowed.",
"requestId": "req_01HQ7K8ABCDEFGHIJKLMNOPQRS"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"status": "INTERNAL",
"message": "An unexpected error occurred.",
"requestId": "req_01HQ7K8ABCDEFGHIJKLMNOPQRS"
}
}Create a custom context item
Creates a customer-owned context item for internal systems or custom databases. Supply idempotencyKey to make repeated creates update the same item.
Requires: context:write
curl --request POST \
--url https://api.getmodus.com/api/v1/context/custom-items \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"kind": "entity",
"sourceId": "billing-db",
"sourceName": "Billing database",
"collectionId": "contracts",
"collectionName": "Contracts",
"externalId": "contract-123",
"name": "Acme renewal contract",
"entityType": "contract",
"description": "Enterprise renewal metadata from the internal billing system.",
"attributes": [
{
"name": "status",
"dataType": "string",
"value": {
"text": "active"
}
}
],
"topics": [
"billing",
"renewals"
]
}
'import requests
url = "https://api.getmodus.com/api/v1/context/custom-items"
payload = {
"kind": "entity",
"sourceId": "billing-db",
"sourceName": "Billing database",
"collectionId": "contracts",
"collectionName": "Contracts",
"externalId": "contract-123",
"name": "Acme renewal contract",
"entityType": "contract",
"description": "Enterprise renewal metadata from the internal billing system.",
"attributes": [
{
"name": "status",
"dataType": "string",
"value": { "text": "active" }
}
],
"topics": ["billing", "renewals"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
kind: 'entity',
sourceId: 'billing-db',
sourceName: 'Billing database',
collectionId: 'contracts',
collectionName: 'Contracts',
externalId: 'contract-123',
name: 'Acme renewal contract',
entityType: 'contract',
description: 'Enterprise renewal metadata from the internal billing system.',
attributes: [{name: 'status', dataType: 'string', value: {text: 'active'}}],
topics: ['billing', 'renewals']
})
};
fetch('https://api.getmodus.com/api/v1/context/custom-items', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.getmodus.com/api/v1/context/custom-items",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'kind' => 'entity',
'sourceId' => 'billing-db',
'sourceName' => 'Billing database',
'collectionId' => 'contracts',
'collectionName' => 'Contracts',
'externalId' => 'contract-123',
'name' => 'Acme renewal contract',
'entityType' => 'contract',
'description' => 'Enterprise renewal metadata from the internal billing system.',
'attributes' => [
[
'name' => 'status',
'dataType' => 'string',
'value' => [
'text' => 'active'
]
]
],
'topics' => [
'billing',
'renewals'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.getmodus.com/api/v1/context/custom-items"
payload := strings.NewReader("{\n \"kind\": \"entity\",\n \"sourceId\": \"billing-db\",\n \"sourceName\": \"Billing database\",\n \"collectionId\": \"contracts\",\n \"collectionName\": \"Contracts\",\n \"externalId\": \"contract-123\",\n \"name\": \"Acme renewal contract\",\n \"entityType\": \"contract\",\n \"description\": \"Enterprise renewal metadata from the internal billing system.\",\n \"attributes\": [\n {\n \"name\": \"status\",\n \"dataType\": \"string\",\n \"value\": {\n \"text\": \"active\"\n }\n }\n ],\n \"topics\": [\n \"billing\",\n \"renewals\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.getmodus.com/api/v1/context/custom-items")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"kind\": \"entity\",\n \"sourceId\": \"billing-db\",\n \"sourceName\": \"Billing database\",\n \"collectionId\": \"contracts\",\n \"collectionName\": \"Contracts\",\n \"externalId\": \"contract-123\",\n \"name\": \"Acme renewal contract\",\n \"entityType\": \"contract\",\n \"description\": \"Enterprise renewal metadata from the internal billing system.\",\n \"attributes\": [\n {\n \"name\": \"status\",\n \"dataType\": \"string\",\n \"value\": {\n \"text\": \"active\"\n }\n }\n ],\n \"topics\": [\n \"billing\",\n \"renewals\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.getmodus.com/api/v1/context/custom-items")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"kind\": \"entity\",\n \"sourceId\": \"billing-db\",\n \"sourceName\": \"Billing database\",\n \"collectionId\": \"contracts\",\n \"collectionName\": \"Contracts\",\n \"externalId\": \"contract-123\",\n \"name\": \"Acme renewal contract\",\n \"entityType\": \"contract\",\n \"description\": \"Enterprise renewal metadata from the internal billing system.\",\n \"attributes\": [\n {\n \"name\": \"status\",\n \"dataType\": \"string\",\n \"value\": {\n \"text\": \"active\"\n }\n }\n ],\n \"topics\": [\n \"billing\",\n \"renewals\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"contextItemId": "7a3f9d2c-1111-4000-a000-000000000abc",
"contextType": "custom_entity_metadata",
"dataPath": [
"billing-db",
"contracts",
"contract-123"
],
"title": "Acme renewal contract"
}{
"error": {
"code": "BAD_REQUEST",
"status": "INVALID_ARGUMENT",
"message": "Invalid value for query parameter `pageSize`.",
"requestId": "req_01HQ7K8ABCDEFGHIJKLMNOPQRS"
}
}{
"error": {
"code": "UNAUTHORIZED",
"status": "UNAUTHENTICATED",
"message": "Missing or invalid access token.",
"requestId": "req_01HQ7K8ABCDEFGHIJKLMNOPQRS"
}
}{
"error": {
"code": "FORBIDDEN",
"status": "PERMISSION_DENIED",
"message": "Missing required scope(s) for this operation.",
"requestId": "req_01HQ7K8ABCDEFGHIJKLMNOPQRS",
"info": {
"missing": [
"<required-scope>"
]
}
}
}{
"error": {
"code": "NOT_FOUND",
"status": "NOT_FOUND",
"message": "Resource not found.",
"requestId": "req_01HQ7K8ABCDEFGHIJKLMNOPQRS"
}
}{
"error": {
"code": "CONFLICT",
"status": "ALREADY_EXISTS",
"message": "A resource with that identifier already exists.",
"requestId": "req_01HQ7K8ABCDEFGHIJKLMNOPQRS"
}
}{
"error": {
"code": "VALIDATION",
"status": "INVALID_ARGUMENT",
"message": "Updates that would revoke your own access are not allowed.",
"requestId": "req_01HQ7K8ABCDEFGHIJKLMNOPQRS"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"status": "INTERNAL",
"message": "An unexpected error occurred.",
"requestId": "req_01HQ7K8ABCDEFGHIJKLMNOPQRS"
}
}Authorizations
A Modus personal access token (modus_<orgUuid>_<prefix>_<secret>) or an OAuth 2.1 access token, sent as Authorization: Bearer <token>.
Body
Shape of custom context item to create.
source, collection, entity, field, entity_samples "entity"
Stable identifier for the customer-defined source.
"billing-db"
Display name for the customer-defined source.
"Billing database"
Stable identifier for the collection inside the source.
"contracts"
Display name for the collection.
"Contracts"
Stable identifier for the entity inside the collection.
"contract-123"
Field name for field-level custom context.
"renewalDate"
Display name for the item.
"Acme renewal contract"
Customer-defined entity or field type.
"contract"
Human-readable description.
"Enterprise contract renewal metadata from the internal billing system."
Main textual or structured content for the custom item.
Customer-facing URL for the source object, when available.
"https://internal.example.com/contracts/contract-123"
Structured attributes for entity-level custom context.
Show child attributes
Show child attributes
Field data type for field-level custom context.
"timestamp"
Representative value for field-level custom context.
Representative samples for entity sample context.
Customer-specific fields that should be retained but are not part of the normalized contract.
Topic tags for filtering.
["billing", "renewals"]
Optional stable key used to make single-item creates idempotent.
"billing-db/contracts/contract-123"
Show child attributes
Show child attributes
Response
Stable uid of the created or updated custom context item.
"7a3f9d2c-1111-4000-a000-000000000abc"
Stored custom context type.
"custom_entity_metadata"
Hierarchical path used to group custom context.
["billing-db", "contracts", "contract-123"]
Display title resolved for the item.
"Acme renewal contract"