curl --request POST \
--url https://api.mixpeek.com/v1/taxonomies/from-documents \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-Namespace: <api-key>' \
--data '
{
"taxonomy_name": "<string>",
"node_label": "<string>",
"documents": [
{
"collection_id": "<string>",
"document_id": "<string>"
}
],
"node_fields": {},
"vector_name": "<string>",
"provenance": {},
"cluster_run": {
"cluster_id": "<string>",
"run_id": "<string>"
},
"description": "<string>",
"enrichment_target_field": "<string>"
}
'import requests
url = "https://api.mixpeek.com/v1/taxonomies/from-documents"
payload = {
"taxonomy_name": "<string>",
"node_label": "<string>",
"documents": [
{
"collection_id": "<string>",
"document_id": "<string>"
}
],
"node_fields": {},
"vector_name": "<string>",
"provenance": {},
"cluster_run": {
"cluster_id": "<string>",
"run_id": "<string>"
},
"description": "<string>",
"enrichment_target_field": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"X-Namespace": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
Authorization: 'Bearer <token>',
'X-Namespace': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
taxonomy_name: '<string>',
node_label: '<string>',
documents: [{collection_id: '<string>', document_id: '<string>'}],
node_fields: {},
vector_name: '<string>',
provenance: {},
cluster_run: {cluster_id: '<string>', run_id: '<string>'},
description: '<string>',
enrichment_target_field: '<string>'
})
};
fetch('https://api.mixpeek.com/v1/taxonomies/from-documents', 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.mixpeek.com/v1/taxonomies/from-documents",
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([
'taxonomy_name' => '<string>',
'node_label' => '<string>',
'documents' => [
[
'collection_id' => '<string>',
'document_id' => '<string>'
]
],
'node_fields' => [
],
'vector_name' => '<string>',
'provenance' => [
],
'cluster_run' => [
'cluster_id' => '<string>',
'run_id' => '<string>'
],
'description' => '<string>',
'enrichment_target_field' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"X-Namespace: <api-key>"
],
]);
$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.mixpeek.com/v1/taxonomies/from-documents"
payload := strings.NewReader("{\n \"taxonomy_name\": \"<string>\",\n \"node_label\": \"<string>\",\n \"documents\": [\n {\n \"collection_id\": \"<string>\",\n \"document_id\": \"<string>\"\n }\n ],\n \"node_fields\": {},\n \"vector_name\": \"<string>\",\n \"provenance\": {},\n \"cluster_run\": {\n \"cluster_id\": \"<string>\",\n \"run_id\": \"<string>\"\n },\n \"description\": \"<string>\",\n \"enrichment_target_field\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("X-Namespace", "<api-key>")
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.mixpeek.com/v1/taxonomies/from-documents")
.header("Authorization", "Bearer <token>")
.header("X-Namespace", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"taxonomy_name\": \"<string>\",\n \"node_label\": \"<string>\",\n \"documents\": [\n {\n \"collection_id\": \"<string>\",\n \"document_id\": \"<string>\"\n }\n ],\n \"node_fields\": {},\n \"vector_name\": \"<string>\",\n \"provenance\": {},\n \"cluster_run\": {\n \"cluster_id\": \"<string>\",\n \"run_id\": \"<string>\"\n },\n \"description\": \"<string>\",\n \"enrichment_target_field\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.mixpeek.com/v1/taxonomies/from-documents")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["X-Namespace"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"taxonomy_name\": \"<string>\",\n \"node_label\": \"<string>\",\n \"documents\": [\n {\n \"collection_id\": \"<string>\",\n \"document_id\": \"<string>\"\n }\n ],\n \"node_fields\": {},\n \"vector_name\": \"<string>\",\n \"provenance\": {},\n \"cluster_run\": {\n \"cluster_id\": \"<string>\",\n \"run_id\": \"<string>\"\n },\n \"description\": \"<string>\",\n \"enrichment_target_field\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"taxonomy_id": "<string>",
"taxonomy_name": "<string>",
"node_document_id": "<string>",
"node_collection_id": "<string>",
"node_label": "<string>",
"vector_name": "<string>",
"vector_dimensions": 123,
"documents_used": 123,
"enrichment_hint": "<string>",
"documents_skipped": [
{
"reason": "<string>",
"collection_id": "<string>",
"document_id": "<string>"
}
],
"taxonomy_created": false,
"retriever_id": "<string>",
"nodes": [
{
"node_document_id": "<string>",
"node_label": "<string>",
"cluster_id": "<string>",
"member_count": 123
}
]
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}Create a taxonomy from a document selection or a cluster run (one gesture)
Promote a document selection (e.g. a lasso/cluster selection in the cluster visualization) into a NEW flat taxonomy in one call.
Creates, in order:
- a node collection mirroring the selection’s vector index (same vector name, dimensions, and feature_uri — no re-embedding, no GPU work),
- a vector-search retriever over it,
- the flat taxonomy wired to both (input_mappings map an incoming document’s stored embedding onto the retriever),
- the nodes, from one of two sources:
documents+node_label: one node whose anchor vector is the centroid of the referenced documents’ stored vectors;cluster_run({cluster_id, run_id}): one node per cluster in that run, labeled with the cluster’s label and anchored on its stored centroid, so a whole cluster run becomes a classifier in one call. The response’snodeslists every node created.
Documents enriched through the taxonomy afterwards are labeled with the
nearest node’s label. To add more nodes later, use
POST /v1/taxonomies/{taxonomy_id}/nodes/from-documents.
Resources created before a failing step are cleaned up best-effort.
curl --request POST \
--url https://api.mixpeek.com/v1/taxonomies/from-documents \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-Namespace: <api-key>' \
--data '
{
"taxonomy_name": "<string>",
"node_label": "<string>",
"documents": [
{
"collection_id": "<string>",
"document_id": "<string>"
}
],
"node_fields": {},
"vector_name": "<string>",
"provenance": {},
"cluster_run": {
"cluster_id": "<string>",
"run_id": "<string>"
},
"description": "<string>",
"enrichment_target_field": "<string>"
}
'import requests
url = "https://api.mixpeek.com/v1/taxonomies/from-documents"
payload = {
"taxonomy_name": "<string>",
"node_label": "<string>",
"documents": [
{
"collection_id": "<string>",
"document_id": "<string>"
}
],
"node_fields": {},
"vector_name": "<string>",
"provenance": {},
"cluster_run": {
"cluster_id": "<string>",
"run_id": "<string>"
},
"description": "<string>",
"enrichment_target_field": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"X-Namespace": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
Authorization: 'Bearer <token>',
'X-Namespace': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
taxonomy_name: '<string>',
node_label: '<string>',
documents: [{collection_id: '<string>', document_id: '<string>'}],
node_fields: {},
vector_name: '<string>',
provenance: {},
cluster_run: {cluster_id: '<string>', run_id: '<string>'},
description: '<string>',
enrichment_target_field: '<string>'
})
};
fetch('https://api.mixpeek.com/v1/taxonomies/from-documents', 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.mixpeek.com/v1/taxonomies/from-documents",
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([
'taxonomy_name' => '<string>',
'node_label' => '<string>',
'documents' => [
[
'collection_id' => '<string>',
'document_id' => '<string>'
]
],
'node_fields' => [
],
'vector_name' => '<string>',
'provenance' => [
],
'cluster_run' => [
'cluster_id' => '<string>',
'run_id' => '<string>'
],
'description' => '<string>',
'enrichment_target_field' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"X-Namespace: <api-key>"
],
]);
$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.mixpeek.com/v1/taxonomies/from-documents"
payload := strings.NewReader("{\n \"taxonomy_name\": \"<string>\",\n \"node_label\": \"<string>\",\n \"documents\": [\n {\n \"collection_id\": \"<string>\",\n \"document_id\": \"<string>\"\n }\n ],\n \"node_fields\": {},\n \"vector_name\": \"<string>\",\n \"provenance\": {},\n \"cluster_run\": {\n \"cluster_id\": \"<string>\",\n \"run_id\": \"<string>\"\n },\n \"description\": \"<string>\",\n \"enrichment_target_field\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("X-Namespace", "<api-key>")
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.mixpeek.com/v1/taxonomies/from-documents")
.header("Authorization", "Bearer <token>")
.header("X-Namespace", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"taxonomy_name\": \"<string>\",\n \"node_label\": \"<string>\",\n \"documents\": [\n {\n \"collection_id\": \"<string>\",\n \"document_id\": \"<string>\"\n }\n ],\n \"node_fields\": {},\n \"vector_name\": \"<string>\",\n \"provenance\": {},\n \"cluster_run\": {\n \"cluster_id\": \"<string>\",\n \"run_id\": \"<string>\"\n },\n \"description\": \"<string>\",\n \"enrichment_target_field\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.mixpeek.com/v1/taxonomies/from-documents")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["X-Namespace"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"taxonomy_name\": \"<string>\",\n \"node_label\": \"<string>\",\n \"documents\": [\n {\n \"collection_id\": \"<string>\",\n \"document_id\": \"<string>\"\n }\n ],\n \"node_fields\": {},\n \"vector_name\": \"<string>\",\n \"provenance\": {},\n \"cluster_run\": {\n \"cluster_id\": \"<string>\",\n \"run_id\": \"<string>\"\n },\n \"description\": \"<string>\",\n \"enrichment_target_field\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"taxonomy_id": "<string>",
"taxonomy_name": "<string>",
"node_document_id": "<string>",
"node_collection_id": "<string>",
"node_label": "<string>",
"vector_name": "<string>",
"vector_dimensions": 123,
"documents_used": 123,
"enrichment_hint": "<string>",
"documents_skipped": [
{
"reason": "<string>",
"collection_id": "<string>",
"document_id": "<string>"
}
],
"taxonomy_created": false,
"retriever_id": "<string>",
"nodes": [
{
"node_document_id": "<string>",
"node_label": "<string>",
"cluster_id": "<string>",
"member_count": 123
}
]
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}Authorizations
Mixpeek API key, sent as Authorization: Bearer mxp_sk_.... Create one in Studio under Settings → API Keys, or with an admin key via POST /v1/organizations/users/{user_email}/api-keys. A missing, malformed, unknown, revoked, inactive or expired key returns 401; a key without the permission, scope or plan an operation needs returns 403.
Namespace id (ns_...), not the namespace name. This scopes the request rather than authenticating it, and it is required on every operation marked x-mixpeek-namespace-scoped.
Body
Keys this body does not declare are ignored, and the response's warnings name them, until 2026-11-02; from 2026-11-02 they are refused with 422 extra_forbidden naming the accepted keys.
One-gesture promotion: create a flat taxonomy (node collection + vector-search retriever) AND its nodes, from a document selection or from a whole cluster run.
The node collection mirrors the source collection's vector index (same vector name / dimensions / feature_uri), so classification is guaranteed dimension-compatible with the data the nodes came from.
Give exactly one source: documents with node_label (one node whose
anchor averages the documents), or cluster_run (one node per cluster
in that run, labelled with the cluster's label, its stored centroid as the
anchor).
Unique name for the new taxonomy.
1Label of the node created from documents. Required with documents; with cluster_run each node takes its cluster's label.
1Documents whose stored vectors are averaged into the one node's anchor. Give this or cluster_run.
1 - 200 elementsShow child attributes
Show child attributes
Optional extra fields stored on the node document (e.g. description). Only fields listed in the taxonomy's enrichment_fields are copied during enrichment.
Optional explicit vector (index) name for the anchor. If omitted, it is derived from the taxonomy's node collection vector indexes.
Optional freeform origin context (e.g. cluster_id, run_id, selection type). Stored on the node document under metadata.promotion for auditability.
Promote a whole cluster run in one call: one node per cluster, labelled with the cluster label, anchored on the cluster's stored centroid vector (no re-embedding). Give this or documents.
Show child attributes
Show child attributes
Optional taxonomy description.
Field name written onto enriched documents (defaults to '<taxonomy_name>_label').
Response
Successful Response
Result of promoting a document selection to a taxonomy node.
ID of the created node document (the taxonomy node).
The taxonomy's node (source) collection.
Vector index name the anchor was stored under.
How many referenced documents contributed to the anchor.
Plain-language description of how the new node will be applied to future data.
Show child attributes
Show child attributes
True when this call also created the taxonomy (one-gesture mode).
Retriever created for the taxonomy (one-gesture mode only).
Every node created, when the source was a cluster_run (one per cluster). node_document_id and node_label name the first.
Show child attributes
Show child attributes
Was this page helpful?

