curl --request POST \
--url https://api.lighton.ai/api/v3/files/{file_id}/facets/batch \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"actions": [
{
"action": "classify",
"content_type_path": "legal:contract:nda"
},
{
"action": "set_value",
"content_type_path": "legal:contract:nda",
"attribute_name": "jurisdiction",
"value": [
"FR",
"DE"
]
},
{
"action": "set_value",
"content_type_path": "legal:contract:nda",
"attribute_name": "counterparty",
"value": "Nimbus Labs"
}
]
}
'import requests
url = "https://api.lighton.ai/api/v3/files/{file_id}/facets/batch"
payload = { "actions": [
{
"action": "classify",
"content_type_path": "legal:contract:nda"
},
{
"action": "set_value",
"content_type_path": "legal:contract:nda",
"attribute_name": "jurisdiction",
"value": ["FR", "DE"]
},
{
"action": "set_value",
"content_type_path": "legal:contract:nda",
"attribute_name": "counterparty",
"value": "Nimbus Labs"
}
] }
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({
actions: [
{action: 'classify', content_type_path: 'legal:contract:nda'},
{
action: 'set_value',
content_type_path: 'legal:contract:nda',
attribute_name: 'jurisdiction',
value: ['FR', 'DE']
},
{
action: 'set_value',
content_type_path: 'legal:contract:nda',
attribute_name: 'counterparty',
value: 'Nimbus Labs'
}
]
})
};
fetch('https://api.lighton.ai/api/v3/files/{file_id}/facets/batch', 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.lighton.ai/api/v3/files/{file_id}/facets/batch",
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([
'actions' => [
[
'action' => 'classify',
'content_type_path' => 'legal:contract:nda'
],
[
'action' => 'set_value',
'content_type_path' => 'legal:contract:nda',
'attribute_name' => 'jurisdiction',
'value' => [
'FR',
'DE'
]
],
[
'action' => 'set_value',
'content_type_path' => 'legal:contract:nda',
'attribute_name' => 'counterparty',
'value' => 'Nimbus Labs'
]
]
]),
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.lighton.ai/api/v3/files/{file_id}/facets/batch"
payload := strings.NewReader("{\n \"actions\": [\n {\n \"action\": \"classify\",\n \"content_type_path\": \"legal:contract:nda\"\n },\n {\n \"action\": \"set_value\",\n \"content_type_path\": \"legal:contract:nda\",\n \"attribute_name\": \"jurisdiction\",\n \"value\": [\n \"FR\",\n \"DE\"\n ]\n },\n {\n \"action\": \"set_value\",\n \"content_type_path\": \"legal:contract:nda\",\n \"attribute_name\": \"counterparty\",\n \"value\": \"Nimbus Labs\"\n }\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.lighton.ai/api/v3/files/{file_id}/facets/batch")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"actions\": [\n {\n \"action\": \"classify\",\n \"content_type_path\": \"legal:contract:nda\"\n },\n {\n \"action\": \"set_value\",\n \"content_type_path\": \"legal:contract:nda\",\n \"attribute_name\": \"jurisdiction\",\n \"value\": [\n \"FR\",\n \"DE\"\n ]\n },\n {\n \"action\": \"set_value\",\n \"content_type_path\": \"legal:contract:nda\",\n \"attribute_name\": \"counterparty\",\n \"value\": \"Nimbus Labs\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.lighton.ai/api/v3/files/{file_id}/facets/batch")
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 \"actions\": [\n {\n \"action\": \"classify\",\n \"content_type_path\": \"legal:contract:nda\"\n },\n {\n \"action\": \"set_value\",\n \"content_type_path\": \"legal:contract:nda\",\n \"attribute_name\": \"jurisdiction\",\n \"value\": [\n \"FR\",\n \"DE\"\n ]\n },\n {\n \"action\": \"set_value\",\n \"content_type_path\": \"legal:contract:nda\",\n \"attribute_name\": \"counterparty\",\n \"value\": \"Nimbus Labs\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"results": [
{
"status": 201,
"data": {
"content_type_path": "legal:contract:nda",
"label": "Non-Disclosure Agreement"
}
},
{
"status": 201,
"data": {
"name": "jurisdiction",
"value": [
"FR",
"DE"
],
"content_type_path": "legal:contract:nda"
}
},
{
"status": 201,
"data": {
"name": "counterparty",
"value": "Nimbus Labs",
"content_type_path": "legal:contract:nda"
}
}
]
}{
"id": null,
"code": 400,
"error": "content_type_unknown",
"detail": "Unknown content type path: 'fake:path'.",
"doc_url": "https://developers.lighton.ai/errors#content_type_unknown",
"index": 1
}{
"id": null,
"code": 401,
"error": "unauthorized",
"detail": "Authentication credentials were not provided or are invalid.",
"doc_url": "https://developers.lighton.ai/errors#unauthorized"
}{
"id": null,
"code": 403,
"error": "insufficient_permissions",
"detail": "You do not have permission to perform this action.",
"doc_url": "https://developers.lighton.ai/errors#insufficient_permissions"
}{
"id": null,
"code": 404,
"error": "not_found",
"detail": "Document not found.",
"doc_url": "https://developers.lighton.ai/errors#not_found"
}{
"id": null,
"code": 422,
"error": "validation_error",
"detail": "One or more fields failed validation.",
"doc_url": "https://developers.lighton.ai/errors#validation_error",
"fields": {
"<field_name>": [
{
"error": "required",
"detail": "This field is required."
}
]
}
}Batch classify and set attribute values
Execute multiple file facet actions in a single request.
All actions are validated upfront before any execution begins. If any action has invalid fields, the entire batch is rejected with a 422 response and no actions are executed.
On domain errors (e.g., unknown content type, sibling conflict), the
batch fails fast at the failing action. The error response includes an
"index" field (0-based) indicating which action caused the failure.
Actions before the failing index are committed; their results are not
returned. All verbs are idempotent — it is safe to re-send the entire
batch after fixing the error.
Request: {"actions": [<action>, <action>, ...]}
Each action object follows the same schema as the single-action
POST /api/v3/files/{file_id}/facets endpoint. Maximum 50 actions per batch.
Response: {"results": [{"status": <code>, "data": <body|null>}, ...]}
Results are in the same order as the input actions. The data key is
null for 204 actions (unclassify, clear_value).
See POST /api/v3/files/{file_id}/facets for available actions and their fields.
Requires edit access to the file.
curl --request POST \
--url https://api.lighton.ai/api/v3/files/{file_id}/facets/batch \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"actions": [
{
"action": "classify",
"content_type_path": "legal:contract:nda"
},
{
"action": "set_value",
"content_type_path": "legal:contract:nda",
"attribute_name": "jurisdiction",
"value": [
"FR",
"DE"
]
},
{
"action": "set_value",
"content_type_path": "legal:contract:nda",
"attribute_name": "counterparty",
"value": "Nimbus Labs"
}
]
}
'import requests
url = "https://api.lighton.ai/api/v3/files/{file_id}/facets/batch"
payload = { "actions": [
{
"action": "classify",
"content_type_path": "legal:contract:nda"
},
{
"action": "set_value",
"content_type_path": "legal:contract:nda",
"attribute_name": "jurisdiction",
"value": ["FR", "DE"]
},
{
"action": "set_value",
"content_type_path": "legal:contract:nda",
"attribute_name": "counterparty",
"value": "Nimbus Labs"
}
] }
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({
actions: [
{action: 'classify', content_type_path: 'legal:contract:nda'},
{
action: 'set_value',
content_type_path: 'legal:contract:nda',
attribute_name: 'jurisdiction',
value: ['FR', 'DE']
},
{
action: 'set_value',
content_type_path: 'legal:contract:nda',
attribute_name: 'counterparty',
value: 'Nimbus Labs'
}
]
})
};
fetch('https://api.lighton.ai/api/v3/files/{file_id}/facets/batch', 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.lighton.ai/api/v3/files/{file_id}/facets/batch",
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([
'actions' => [
[
'action' => 'classify',
'content_type_path' => 'legal:contract:nda'
],
[
'action' => 'set_value',
'content_type_path' => 'legal:contract:nda',
'attribute_name' => 'jurisdiction',
'value' => [
'FR',
'DE'
]
],
[
'action' => 'set_value',
'content_type_path' => 'legal:contract:nda',
'attribute_name' => 'counterparty',
'value' => 'Nimbus Labs'
]
]
]),
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.lighton.ai/api/v3/files/{file_id}/facets/batch"
payload := strings.NewReader("{\n \"actions\": [\n {\n \"action\": \"classify\",\n \"content_type_path\": \"legal:contract:nda\"\n },\n {\n \"action\": \"set_value\",\n \"content_type_path\": \"legal:contract:nda\",\n \"attribute_name\": \"jurisdiction\",\n \"value\": [\n \"FR\",\n \"DE\"\n ]\n },\n {\n \"action\": \"set_value\",\n \"content_type_path\": \"legal:contract:nda\",\n \"attribute_name\": \"counterparty\",\n \"value\": \"Nimbus Labs\"\n }\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.lighton.ai/api/v3/files/{file_id}/facets/batch")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"actions\": [\n {\n \"action\": \"classify\",\n \"content_type_path\": \"legal:contract:nda\"\n },\n {\n \"action\": \"set_value\",\n \"content_type_path\": \"legal:contract:nda\",\n \"attribute_name\": \"jurisdiction\",\n \"value\": [\n \"FR\",\n \"DE\"\n ]\n },\n {\n \"action\": \"set_value\",\n \"content_type_path\": \"legal:contract:nda\",\n \"attribute_name\": \"counterparty\",\n \"value\": \"Nimbus Labs\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.lighton.ai/api/v3/files/{file_id}/facets/batch")
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 \"actions\": [\n {\n \"action\": \"classify\",\n \"content_type_path\": \"legal:contract:nda\"\n },\n {\n \"action\": \"set_value\",\n \"content_type_path\": \"legal:contract:nda\",\n \"attribute_name\": \"jurisdiction\",\n \"value\": [\n \"FR\",\n \"DE\"\n ]\n },\n {\n \"action\": \"set_value\",\n \"content_type_path\": \"legal:contract:nda\",\n \"attribute_name\": \"counterparty\",\n \"value\": \"Nimbus Labs\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"results": [
{
"status": 201,
"data": {
"content_type_path": "legal:contract:nda",
"label": "Non-Disclosure Agreement"
}
},
{
"status": 201,
"data": {
"name": "jurisdiction",
"value": [
"FR",
"DE"
],
"content_type_path": "legal:contract:nda"
}
},
{
"status": 201,
"data": {
"name": "counterparty",
"value": "Nimbus Labs",
"content_type_path": "legal:contract:nda"
}
}
]
}{
"id": null,
"code": 400,
"error": "content_type_unknown",
"detail": "Unknown content type path: 'fake:path'.",
"doc_url": "https://developers.lighton.ai/errors#content_type_unknown",
"index": 1
}{
"id": null,
"code": 401,
"error": "unauthorized",
"detail": "Authentication credentials were not provided or are invalid.",
"doc_url": "https://developers.lighton.ai/errors#unauthorized"
}{
"id": null,
"code": 403,
"error": "insufficient_permissions",
"detail": "You do not have permission to perform this action.",
"doc_url": "https://developers.lighton.ai/errors#insufficient_permissions"
}{
"id": null,
"code": 404,
"error": "not_found",
"detail": "Document not found.",
"doc_url": "https://developers.lighton.ai/errors#not_found"
}{
"id": null,
"code": 422,
"error": "validation_error",
"detail": "One or more fields failed validation.",
"doc_url": "https://developers.lighton.ai/errors#validation_error",
"fields": {
"<field_name>": [
{
"error": "required",
"detail": "This field is required."
}
]
}
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Body
Batch request for file facet operations.
All actions are validated upfront before any execution begins.
1 - 50 elementsShow child attributes
Show child attributes
Response
All actions executed successfully
Show child attributes
Show child attributes