curl --request GET \
--url https://api-prod.studio.getsupervisor.ai/v1/uploads/{uploadId} \
--header 'Authorization: Bearer <token>' \
--header 'x-workspace-id: <x-workspace-id>'import requests
url = "https://api-prod.studio.getsupervisor.ai/v1/uploads/{uploadId}"
headers = {
"x-workspace-id": "<x-workspace-id>",
"Authorization": "Bearer <token>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {'x-workspace-id': '<x-workspace-id>', Authorization: 'Bearer <token>'}
};
fetch('https://api-prod.studio.getsupervisor.ai/v1/uploads/{uploadId}', 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-prod.studio.getsupervisor.ai/v1/uploads/{uploadId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"x-workspace-id: <x-workspace-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-prod.studio.getsupervisor.ai/v1/uploads/{uploadId}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-workspace-id", "<x-workspace-id>")
req.Header.Add("Authorization", "Bearer <token>")
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-prod.studio.getsupervisor.ai/v1/uploads/{uploadId}")
.header("x-workspace-id", "<x-workspace-id>")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-prod.studio.getsupervisor.ai/v1/uploads/{uploadId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-workspace-id"] = '<x-workspace-id>'
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"uploadId": "7f3a1b2c-9d4e-4f6a-8b1c-2d3e4f5a6b7c",
"namespace": "knowledge-sources",
"status": "pending",
"originalFileName": "manual-cobranza.pdf",
"contentType": "application/pdf",
"declaredSizeBytes": 348172,
"sizeBytes": null,
"rejectedReason": null,
"createdBy": "usr_2f1c",
"createdAt": "2026-09-04T22:30:00.000Z",
"confirmedAt": null
}Consultar una subida
En qué punto está el archivo: si sigue esperando confirmación, si ya es utilizable, o si se rechazó y por qué.
No devuelve la storageKey. Dónde vive el objeto es asunto del almacén; publicarlo
sólo serviría para que alguien construyera rutas a mano.
curl --request GET \
--url https://api-prod.studio.getsupervisor.ai/v1/uploads/{uploadId} \
--header 'Authorization: Bearer <token>' \
--header 'x-workspace-id: <x-workspace-id>'import requests
url = "https://api-prod.studio.getsupervisor.ai/v1/uploads/{uploadId}"
headers = {
"x-workspace-id": "<x-workspace-id>",
"Authorization": "Bearer <token>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {'x-workspace-id': '<x-workspace-id>', Authorization: 'Bearer <token>'}
};
fetch('https://api-prod.studio.getsupervisor.ai/v1/uploads/{uploadId}', 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-prod.studio.getsupervisor.ai/v1/uploads/{uploadId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"x-workspace-id: <x-workspace-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-prod.studio.getsupervisor.ai/v1/uploads/{uploadId}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-workspace-id", "<x-workspace-id>")
req.Header.Add("Authorization", "Bearer <token>")
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-prod.studio.getsupervisor.ai/v1/uploads/{uploadId}")
.header("x-workspace-id", "<x-workspace-id>")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-prod.studio.getsupervisor.ai/v1/uploads/{uploadId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-workspace-id"] = '<x-workspace-id>'
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"uploadId": "7f3a1b2c-9d4e-4f6a-8b1c-2d3e4f5a6b7c",
"namespace": "knowledge-sources",
"status": "pending",
"originalFileName": "manual-cobranza.pdf",
"contentType": "application/pdf",
"declaredSizeBytes": 348172,
"sizeBytes": null,
"rejectedReason": null,
"createdBy": "usr_2f1c",
"createdAt": "2026-09-04T22:30:00.000Z",
"confirmedAt": null
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Headers
Identificador del workspace multi-tenant.
Path Parameters
La fila que dejó el presign. El namespace no viaja en estas rutas: sale de la fila, porque consultarlo antes de autorizar exigiría leer la base para decidir el permiso, y eso filtraría si un id existe a quien no debería saberlo.
Response
El estado de la subida.
Lo que se sabe de un archivo subido, mirado desde fuera.
Destino del archivo. Es un conjunto cerrado y versionado en el código: cada namespace trae su propia política de formatos, tamaños y permisos.
agent-briefs, knowledge-sources En qué punto del ciclo está el archivo.
pending es la fila que dejó el presign: existe antes de que se suba un solo byte, y
caduca a las 24 h si nadie la confirma. ready es el archivo verificado —sigue siendo
operable: se puede reclamar y se puede descartar—. rejected, expired y discarded
son estados de los que ya no se sale.
pending, ready, rejected, expired, discarded El nombre con el que el cliente lo mandó, sin normalizar.
El tamaño que el cliente dijo al pedir el presign.
El tamaño real del objeto, medido al confirmar. Es null mientras nadie lo haya
mirado — está aparte de declaredSizeBytes precisamente porque pueden no coincidir.
Por qué se rechazó, cuando status es rejected. Si no, null.
Es un código, no una frase: hoy size-mismatch (lo medido no cuadra con lo
declarado) o content-mismatch (los bytes no son del formato que dice la
extensión). El detalle legible va en el mensaje del 422, no aquí.
"content-mismatch"
