curl --request GET \
--url https://api.mentionlab.io/api/projects/theme-analysis/status \
--header 'x-project-id: <x-project-id>'import requests
url = "https://api.mentionlab.io/api/projects/theme-analysis/status"
headers = {"x-project-id": "<x-project-id>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-project-id': '<x-project-id>'}};
fetch('https://api.mentionlab.io/api/projects/theme-analysis/status', 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.mentionlab.io/api/projects/theme-analysis/status",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-project-id: <x-project-id>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.mentionlab.io/api/projects/theme-analysis/status"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-project-id", "<x-project-id>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.mentionlab.io/api/projects/theme-analysis/status")
.header("x-project-id", "<x-project-id>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.mentionlab.io/api/projects/theme-analysis/status")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-project-id"] = '<x-project-id>'
response = http.request(request)
puts response.read_body{
"status": "running",
"enabled": true,
"pendingJobs": 3,
"analyzedJobs": 28,
"unclusteredMentions": 14,
"themeMentions": 412,
"themes": 23,
"lastActivityAt": "2026-06-25T10:12:04.000Z",
"lastRun": {
"startedAt": "2026-07-14T10:12:04.000Z",
"finishedAt": "2026-07-14T10:18:41.000Z"
}
}{
"statusCode": 400,
"message": "Validation failed",
"error": "Bad Request"
}{
"statusCode": 400,
"message": "Validation failed",
"error": "Bad Request"
}{
"statusCode": 400,
"message": "Validation failed",
"error": "Bad Request"
}Theme-analysis pipeline status for the project
Read-only progress snapshot: whether an analysis is running (extraction/clustering in flight), pending (completed prompt runs queued for the next poll), or idle (up to date), plus the underlying counts.
curl --request GET \
--url https://api.mentionlab.io/api/projects/theme-analysis/status \
--header 'x-project-id: <x-project-id>'import requests
url = "https://api.mentionlab.io/api/projects/theme-analysis/status"
headers = {"x-project-id": "<x-project-id>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-project-id': '<x-project-id>'}};
fetch('https://api.mentionlab.io/api/projects/theme-analysis/status', 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.mentionlab.io/api/projects/theme-analysis/status",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-project-id: <x-project-id>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.mentionlab.io/api/projects/theme-analysis/status"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-project-id", "<x-project-id>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.mentionlab.io/api/projects/theme-analysis/status")
.header("x-project-id", "<x-project-id>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.mentionlab.io/api/projects/theme-analysis/status")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-project-id"] = '<x-project-id>'
response = http.request(request)
puts response.read_body{
"status": "running",
"enabled": true,
"pendingJobs": 3,
"analyzedJobs": 28,
"unclusteredMentions": 14,
"themeMentions": 412,
"themes": 23,
"lastActivityAt": "2026-06-25T10:12:04.000Z",
"lastRun": {
"startedAt": "2026-07-14T10:12:04.000Z",
"finishedAt": "2026-07-14T10:18:41.000Z"
}
}{
"statusCode": 400,
"message": "Validation failed",
"error": "Bad Request"
}{
"statusCode": 400,
"message": "Validation failed",
"error": "Bad Request"
}{
"statusCode": 400,
"message": "Validation failed",
"error": "Bad Request"
}Headers
Project ID to specify the project context
Response
Coarse pipeline state. running = mentions are being extracted/clustered right now; pending = completed prompt runs are queued for the next poll (~1 min); failed = the last cluster pass failed or was killed (OOM/SIGKILL) and the project is not converging — see lastRun; idle = nothing outstanding, the project is up to date.
idle, pending, running, failed "running"
Whether theme analysis is enabled for this project.
true
Completed prompt runs not yet handed off to analysis (the poller will pick them up within ~1 min).
3
Completed prompt runs already handed off to analysis.
28
Theme mentions extracted but not yet assigned a theme (clustering in flight).
14
Total theme mentions extracted for this project so far.
412
Distinct themes the project mentions have resolved into.
23
ISO timestamp of the most recent extracted mention, or null if none yet.
"2026-06-25T10:12:04.000Z"
The last stage-3 cluster pass, or null if the project has never been clustered.
Show child attributes
Show child attributes