Reserva un sitio para cada archivo y devuelve la URL con la que el cliente lo sube
directamente al almacén: la API nunca ve los bytes.
El namespace va en la ruta porque identifica el destino del archivo, y cada uno
tiene su propia política —qué extensiones acepta, cuánto pesa como mucho cada archivo,
cuántos admite una petición y qué scope exige—. Uno de los permisos lo decide ese
namespace: agent-briefs pide agents:write y knowledge-sources pide
knowledge-bases:write.
Y hace falta además uploads:write, que es el mismo que exigen confirm y DELETE.
Son dos preguntas distintas —«puedes escribir en este destino» y «puedes manejar archivos
subidos»— y firmar sin la segunda dejaría pasar una petición que no va a poder cerrar el
ciclo: el objeto llegaría a S3 sin forma de confirmarlo ni descartarlo.
Cada archivo deja una fila creada antes de firmar, y por eso la respuesta es 201
aunque todavía no se haya subido un solo byte: esa fila es lo que hace localizable a un
archivo que nunca llegue a subirse. La operación no es idempotente: dos llamadas
dan dos uploadId y dos filas, y la que no se confirme caduca a las 24 h.
El carril está detrás de un feature flag por workspace. Cerrado, responde 404.
Identificador del workspace multi-tenant. Obligatorio al autenticar con Authorization: Bearer, donde su ausencia devuelve 400 Workspace context is required. Con x-api-key es opcional: la llave ya identifica a su workspace y lo que mandes aquí se ignora.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Agents Studio Docs","colors":{"primary":"#0ea5e9","light":"#f0f9ff","dark":"#082f49"},"logo":{"light":"https://mintcdn.com/supervisorai/aFOceNtmZJygjrCt/logo/leracom.png?fit=max\u0026auto=format\u0026n=aFOceNtmZJygjrCt\u0026q=85\u0026s=50cc1af96825067fbe033d98f4ba5e29","dark":"https://mintcdn.com/supervisorai/aFOceNtmZJygjrCt/logo/leracom.png?fit=max\u0026auto=format\u0026n=aFOceNtmZJygjrCt\u0026q=85\u0026s=50cc1af96825067fbe033d98f4ba5e29"},"favicon":"https://mintcdn.com/supervisorai/aFOceNtmZJygjrCt/favicon.svg?fit=max\u0026auto=format\u0026n=aFOceNtmZJygjrCt\u0026q=85\u0026s=64d7e96a6622a26f64dcbcaba4b2f2c8","navbar":{"links":[{"href":"mailto:sistemas@getsupervisor.ai","label":"Soporte"}],"primary":{"type":"button","label":"Agents Studio","href":"https://agents.studio.getsupervisor.ai"}},"footer":{"socials":{"linkedin":"https://www.linkedin.com/company/supervisor-ai","facebook":"https://www.facebook.com/profile.php?id=61551044721614","instagram":"https://www.instagram.com/supervisor.ai"}},"contextual":{"options":["copy","view","chatgpt","claude","perplexity","mcp","cursor","vscode"],"display":"header"},"styling":{"latex":false},"navigation":{"global":{},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"supervisorai","hasAudioNarration":false,"actualSubdomain":"supervisorai","customDomains":["docs.getsupervisor.ai"],"gitSource":{"type":"github","owner":"julio-supervisor","repo":"agents-studio-be","deployBranch":"develop","contentDirectory":"apps/public-api/docs","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ab558748ee556b966258d15","collectionId":"f6c76ef9-c41f-415a-9695-f8ddf06aaa2b","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ab558748ee556b966258d15"},"entitlements":{},"buildId":"6ab558748ee556b966258d15","clientVersion":"0.0.3971","searchFilterCounts":[{"language":"default","tag":"Referencia API","count":130},{"language":"default","tag":"Referencia de endpoints","count":113},{"language":"default","tag":"Webhooks","count":14},{"language":"default","tag":"Blog","count":10},{"language":"default","tag":"Agent Schedules","count":9},{"language":"default","tag":"Agents","count":8},{"language":"default","tag":"Campaigns","count":8},{"language":"default","tag":"Knowledge Bases","count":7},{"language":"default","tag":"Tools","count":7},{"language":"default","tag":"Agent Versions","count":6}]},"assistantConfig":{},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-v7-file-tree","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-nav-generations","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-agent-model-picker","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"isAtlas":false,"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"api-reference/uploads/pedir-subir-archivos-a-un-destino","slug":"/api-reference/uploads/pedir-subir-archivos-a-un-destino","pageMetadata":{"title":"Pedir subir archivos a un destino","description":"Reserva un sitio para cada archivo y devuelve la URL con la que el cliente lo sube\ndirectamente al almacén: la API nunca ve los bytes.\n\nEl **namespace va en la ruta** porque identifica el destino del archivo, y cada uno\ntiene su propia política —qué extensiones acepta, cuánto pesa como mucho cada archivo,\ncuántos admite una petición y qué scope exige—. Uno de los permisos lo decide ese\nnamespace: `agent-briefs` pide `agents:write` y `knowledge-sources` pide\n`knowledge-bases:write`.\n\nY hace falta **además `uploads:write`**, que es el mismo que exigen `confirm` y `DELETE`.\nSon dos preguntas distintas —«puedes escribir en este destino» y «puedes manejar archivos\nsubidos»— y firmar sin la segunda dejaría pasar una petición que no va a poder cerrar el\nciclo: el objeto llegaría a S3 sin forma de confirmarlo ni descartarlo.\n\nCada archivo deja una fila creada **antes** de firmar, y por eso la respuesta es `201`\naunque todavía no se haya subido un solo byte: esa fila es lo que hace localizable a un\narchivo que nunca llegue a subirse. La operación **no es idempotente**: dos llamadas\ndan dos `uploadId` y dos filas, y la que no se confirme caduca a las 24 h.\n\nEl carril está detrás de un feature flag por workspace. Cerrado, responde `404`.\n","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/uploads/{namespace}","href":"/api-reference/uploads/pedir-subir-archivos-a-un-destino","autogeneratedByOpenApi":true},"description":{"compiledSource":"\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n p: \"p\",\n strong: \"strong\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsx(_components.p, {\n children: \"Reserva un sitio para cada archivo y devuelve la URL con la que el cliente lo sube\\ndirectamente al almacén: la API nunca ve los bytes.\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"El \", _jsx(_components.strong, {\n children: \"namespace va en la ruta\"\n }), \" porque identifica el destino del archivo, y cada uno\\ntiene su propia política —qué extensiones acepta, cuánto pesa como mucho cada archivo,\\ncuántos admite una petición y qué scope exige—. Uno de los permisos lo decide ese\\nnamespace: \", _jsx(_components.code, {\n children: \"agent-briefs\"\n }), \" pide \", _jsx(_components.code, {\n children: \"agents:write\"\n }), \" y \", _jsx(_components.code, {\n children: \"knowledge-sources\"\n }), \" pide\\n\", _jsx(_components.code, {\n children: \"knowledge-bases:write\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Y hace falta \", _jsxs(_components.strong, {\n children: [\"además \", _jsx(_components.code, {\n children: \"uploads:write\"\n })]\n }), \", que es el mismo que exigen \", _jsx(_components.code, {\n children: \"confirm\"\n }), \" y \", _jsx(_components.code, {\n children: \"DELETE\"\n }), \".\\nSon dos preguntas distintas —«puedes escribir en este destino» y «puedes manejar archivos\\nsubidos»— y firmar sin la segunda dejaría pasar una petición que no va a poder cerrar el\\nciclo: el objeto llegaría a S3 sin forma de confirmarlo ni descartarlo.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Cada archivo deja una fila creada \", _jsx(_components.strong, {\n children: \"antes\"\n }), \" de firmar, y por eso la respuesta es \", _jsx(_components.code, {\n children: \"201\"\n }), \"\\naunque todavía no se haya subido un solo byte: esa fila es lo que hace localizable a un\\narchivo que nunca llegue a subirse. La operación \", _jsx(_components.strong, {\n children: \"no es idempotente\"\n }), \": dos llamadas\\ndan dos \", _jsx(_components.code, {\n children: \"uploadId\"\n }), \" y dos filas, y la que no se confirme caduca a las 24 h.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"El carril está detrás de un feature flag por workspace. Cerrado, responde \", _jsx(_components.code, {\n children: \"404\"\n }), \".\"]\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Pedir subir archivos a un destino","description":"Reserva un sitio para cada archivo y devuelve la URL con la que el cliente lo sube\ndirectamente al almacén: la API nunca ve los bytes.\n\nEl **namespace va en la ruta** porque identifica el destino del archivo, y cada uno\ntiene su propia política —qué extensiones acepta, cuánto pesa como mucho cada archivo,\ncuántos admite una petición y qué scope exige—. Uno de los permisos lo decide ese\nnamespace: `agent-briefs` pide `agents:write` y `knowledge-sources` pide\n`knowledge-bases:write`.\n\nY hace falta **además `uploads:write`**, que es el mismo que exigen `confirm` y `DELETE`.\nSon dos preguntas distintas —«puedes escribir en este destino» y «puedes manejar archivos\nsubidos»— y firmar sin la segunda dejaría pasar una petición que no va a poder cerrar el\nciclo: el objeto llegaría a S3 sin forma de confirmarlo ni descartarlo.\n\nCada archivo deja una fila creada **antes** de firmar, y por eso la respuesta es `201`\naunque todavía no se haya subido un solo byte: esa fila es lo que hace localizable a un\narchivo que nunca llegue a subirse. La operación **no es idempotente**: dos llamadas\ndan dos `uploadId` y dos filas, y la que no se confirme caduca a las 24 h.\n\nEl carril está detrás de un feature flag por workspace. Cerrado, responde `404`.\n","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/uploads/{namespace}","href":"/api-reference/uploads/pedir-subir-archivos-a-un-destino","autogeneratedByOpenApi":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"tags":["Uploads"],"summary":"Pedir subir archivos a un destino","description":"Reserva un sitio para cada archivo y devuelve la URL con la que el cliente lo sube\ndirectamente al almacén: la API nunca ve los bytes.\n\nEl **namespace va en la ruta** porque identifica el destino del archivo, y cada uno\ntiene su propia política —qué extensiones acepta, cuánto pesa como mucho cada archivo,\ncuántos admite una petición y qué scope exige—. Uno de los permisos lo decide ese\nnamespace: `agent-briefs` pide `agents:write` y `knowledge-sources` pide\n`knowledge-bases:write`.\n\nY hace falta **además `uploads:write`**, que es el mismo que exigen `confirm` y `DELETE`.\nSon dos preguntas distintas —«puedes escribir en este destino» y «puedes manejar archivos\nsubidos»— y firmar sin la segunda dejaría pasar una petición que no va a poder cerrar el\nciclo: el objeto llegaría a S3 sin forma de confirmarlo ni descartarlo.\n\nCada archivo deja una fila creada **antes** de firmar, y por eso la respuesta es `201`\naunque todavía no se haya subido un solo byte: esa fila es lo que hace localizable a un\narchivo que nunca llegue a subirse. La operación **no es idempotente**: dos llamadas\ndan dos `uploadId` y dos filas, y la que no se confirme caduca a las 24 h.\n\nEl carril está detrás de un feature flag por workspace. Cerrado, responde `404`.\n","operationId":"presignUploads","parameters":["614f06b1-f7e2-47b0-853d-1279e4b8ddb5","ca1ea411-79d5-49e3-bc4f-a30787876a00"],"requestBody":"3f6db913-e03b-42ad-8610-25f51ea89fea","responses":{"201":"8ff75e23-bc9f-4400-b7e9-a80ace6e250c","400":"d43271c0-bfb3-41ab-8c1a-e88ee5e1311b","403":"6736f51d-03e3-4462-928d-2430ead1171e","404":"4e4aa60c-0faf-4c7c-9ae1-54dea8d48a4f","413":"7ab9edc9-71f2-4827-bd4f-2725c824e756"},"method":"post","type":"path","servers":["0be97b1f-0dc6-4cbd-a6d4-29e384bd2b64","41f9c1e2-e079-49e6-8b36-a71dbc10245d"],"security":["8ea4ebc0-2531-4937-b95c-7a0510429de3","615db291-8983-49c9-a781-a5630059c2a7"],"path":"/v1/uploads/{namespace}","baseUrlOptions":["https://api-prod.studio.getsupervisor.ai","https://sandbox.agents.studio.getsupervisor.ai"],"title":"Pedir subir archivos a un destino","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{"614f06b1-f7e2-47b0-853d-1279e4b8ddb5":{"name":"x-workspace-id","in":"header","required":false,"description":"Identificador del workspace multi-tenant. **Obligatorio al autenticar con `Authorization: Bearer`**, donde su ausencia devuelve `400 Workspace context is required`. Con `x-api-key` es opcional: la llave ya identifica a su workspace y lo que mandes aquí se ignora.","schema":{"type":"string","format":"uuid","isRequired":false,"description":"Identificador del workspace multi-tenant. **Obligatorio al autenticar con `Authorization: Bearer`**, donde su ausencia devuelve `400 Workspace context is required`. Con `x-api-key` es opcional: la llave ya identifica a su workspace y lo que mandes aquí se ignora.","uniqueKey":"","typeLabel":"string\u003cuuid>"}},"ca1ea411-79d5-49e3-bc4f-a30787876a00":{"name":"namespace","in":"path","required":true,"schema":{"type":"string","enum":["agent-briefs","knowledge-sources"],"description":"Destino del archivo. Es un conjunto cerrado y versionado en el código: cada namespace\ntrae su propia política de formatos, tamaños y permisos.\n","isRequired":true,"uniqueKey":"","typeLabel":"enum\u003cstring>"}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Los archivos que se quieren subir a este namespace.","properties":{"files":{"type":"array","items":{"type":"object","description":"Un archivo del lote. `fileName` es una etiqueta, no una ruta: de él sólo se lee la\nextensión, y sólo para validarla contra la lista cerrada del namespace. Nunca entra a\nla `key`, que es lo que hace irrepresentable el path traversal.\n","properties":{"fileName":{"type":"string","maxLength":255,"description":"Nombre original del archivo, con su extensión.","isRequired":true,"uniqueKey":"files.items.[INDEX].fileName","typeLabel":"string"},"sizeBytes":{"type":"integer","minimum":1,"description":"Lo que el cliente dice que pesa. Se valida contra la política del namespace y se\nfirma como `Content-Length`, así que el almacén rechaza el PUT que no lo respete.\n","isRequired":true,"uniqueKey":"files.items.[INDEX].sizeBytes","typeLabel":"integer"}},"required":["fileName","sizeBytes"],"uniqueKey":"files.items.[INDEX]","typeLabel":"object"},"minItems":1,"maxItems":25,"isRequired":true,"uniqueKey":"files","typeLabel":"object[]"}},"required":["files"],"uniqueKey":"","typeLabel":"object"},"examples":{"twoFiles":{"title":"twoFiles","value":{"files":[{"fileName":"manual-cobranza.pdf","sizeBytes":348172},{"fileName":"guion-llamadas.docx","sizeBytes":91240}]}}},"exampleType":"examples"}},"exampleType":"examples"},"responses":{"8ff75e23-bc9f-4400-b7e9-a80ace6e250c":{"description":"Sitio reservado y URLs de subida emitidas","content":{"application/json":{"schema":{"type":"object","properties":{"uploads":{"type":"array","items":{"type":"object","properties":{"uploadId":{"type":"string","format":"uuid","description":"La fila que ya existe para este archivo. Es con lo que se confirma luego.","isRequired":true,"uniqueKey":"uploads.items.[INDEX].uploadId","typeLabel":"string\u003cuuid>"},"namespace":{"type":"string","enum":["agent-briefs","knowledge-sources"],"description":"Destino del archivo. Es un conjunto cerrado y versionado en el código: cada namespace\ntrae su propia política de formatos, tamaños y permisos.\n","isRequired":true,"uniqueKey":"uploads.items.[INDEX].namespace","typeLabel":"enum\u003cstring>"},"key":{"type":"string","description":"Dónde vivirá el objeto en el almacén.","isRequired":true,"uniqueKey":"uploads.items.[INDEX].key","typeLabel":"string"},"uploadUrl":{"type":"string","format":"uri","description":"URL prefirmada contra la que el cliente sube el archivo.","isRequired":true,"uniqueKey":"uploads.items.[INDEX].uploadUrl","typeLabel":"string\u003curi>"},"method":{"type":"string","enum":["PUT"],"isRequired":true,"uniqueKey":"uploads.items.[INDEX].method","typeLabel":"enum\u003cstring>"},"headers":{"type":"object","additionalProperties":{"type":"string","uniqueKey":"uploads.items.[INDEX].headers.additionalProperties","typeLabel":"string"},"description":"Los headers exactos que hay que reenviar, ni uno más ni uno menos.\n`Content-Length` no aparece aunque vaya firmado: es un *forbidden header name* y el\n`fetch` del navegador lo pone él desde el Blob.\n","isRequired":true,"uniqueKey":"uploads.items.[INDEX].headers","typeLabel":"object"},"urlExpiresAt":{"type":"string","format":"date-time","description":"Cuándo vence **esta URL** (15 min). No confundir con el plazo de staging de la\nfila, que es de 24 h.\n","isRequired":true,"uniqueKey":"uploads.items.[INDEX].urlExpiresAt","typeLabel":"string\u003cdate-time>"}},"required":["uploadId","namespace","key","uploadUrl","method","headers","urlExpiresAt"],"uniqueKey":"uploads.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"uploads","typeLabel":"object[]"}},"required":["uploads"],"uniqueKey":"","typeLabel":"object"},"examples":{"created":{"title":"created","value":{"uploads":[{"uploadId":"7f3a1b2c-9d4e-4f6a-8b1c-2d3e4f5a6b7c","namespace":"agent-briefs","key":"agent-briefs/a44bb95e-0000-4000-8000-000000000001/7f3a1b2c-9d4e-4f6a-8b1c-2d3e4f5a6b7c.pdf","uploadUrl":"https://bucket.s3.amazonaws.com/agent-briefs/...?X-Amz-...","method":"PUT","headers":{"Content-Type":"application/pdf"},"urlExpiresAt":"2026-09-04T22:45:00.000Z"}]}}},"exampleType":"examples"}},"exampleType":"examples"},"d43271c0-bfb3-41ab-8c1a-e88ee5e1311b":{"description":"El namespace no existe, una extensión no está en su lista, o el lote trae más\narchivos de los que ese namespace admite.\n","content":{"application/json":{"schema":{"type":"object","description":"Forma común de los errores de la API. El filtro global responde\n`{ statusCode, error, message, path, timestamp }`; los 400 que produce la validación del\nbody llegan con `message` como arreglo de strings (uno por regla incumplida) y sin\n`path` ni `timestamp`.\n\n`code` y `details` **no** son parte del contrato general: sólo los traen los rechazos\nque los construyen explícitamente (por ejemplo `UPLOAD_REJECTED_BY_NAMESPACE` al\nreutilizar un archivo en otro namespace, o `PROVIDER_CAPACITY_EXHAUSTED` en un 429).\nNo ramifiques por `code` en el resto de las rutas: ahí no viene.\n","properties":{"statusCode":{"type":"integer","description":"Código HTTP de la respuesta.","isRequired":true,"uniqueKey":"statusCode","typeLabel":"integer"},"message":{"oneOf":[{"type":"string","description":"Mensaje legible para humanos. Es un arreglo cuando el 400 viene de la validación del body.","isRequired":true,"uniqueKey":"message.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"string","uniqueKey":"message.oneOf.1.items.[INDEX]","typeLabel":"string"},"description":"Mensaje legible para humanos. Es un arreglo cuando el 400 viene de la validación del body.","isRequired":true,"uniqueKey":"message.oneOf.1","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"message","typeLabel":"string | string[]"},"error":{"type":"string","description":"Etiqueta HTTP del estado (`Bad Request`, `Not Found`, …).","uniqueKey":"error","typeLabel":"string"},"path":{"type":"string","description":"Ruta de la petición que falló. Presente en los errores que emite el filtro global.","uniqueKey":"path","typeLabel":"string"},"timestamp":{"type":"string","format":"date-time","description":"Momento en que se generó la respuesta de error. Presente en los errores que emite el filtro global.","uniqueKey":"timestamp","typeLabel":"string\u003cdate-time>"},"code":{"type":"string","description":"Identificador estable del rechazo. Sólo en los errores que lo declaran; ausente en el resto.","uniqueKey":"code","typeLabel":"string"},"details":{"type":"object","description":"Información adicional específica del error, presente sólo cuando el rechazo la construye.\nCuando aplique, `details.subcode` provee un identificador estable para que el frontend decida qué UI mostrar.\n","properties":{"subcode":{"type":"string","description":"Identificador específico del error (p.ej. `WORKSPACE_NOT_PROVISIONED`).","uniqueKey":"details.subcode","typeLabel":"string"},"workspaceId":{"type":"string","format":"uuid","description":"Identificador de workspace relacionado cuando aplica.","uniqueKey":"details.workspaceId","typeLabel":"string\u003cuuid>"}},"additionalProperties":true,"uniqueKey":"details","typeLabel":"object"}},"required":["statusCode","message"],"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"statusCode":123,"message":"\u003cstring>","error":"\u003cstring>","path":"\u003cstring>","timestamp":"2023-11-07T05:31:56Z","code":"\u003cstring>","details":{"subcode":"\u003cstring>","workspaceId":"3c90c3cc-0d44-4b50-8888-8dd25736052a"}}}},"exampleType":"generated"}},"exampleType":"generated"},"6736f51d-03e3-4462-928d-2430ead1171e":{"description":"A la petición le falta alguno de los **dos** scopes que exige firmar: el que pide el\nnamespace de destino (`agents:write` para `agent-briefs`, `knowledge-bases:write`\npara `knowledge-sources`) y `uploads:write`. El mensaje nombra **todos** los que\nfaltan, no el primero: con uno solo haría falta una segunda vuelta para descubrir\nel otro.\n","content":{"application/json":{"schema":{"type":"object","description":"Forma común de los errores de la API. El filtro global responde\n`{ statusCode, error, message, path, timestamp }`; los 400 que produce la validación del\nbody llegan con `message` como arreglo de strings (uno por regla incumplida) y sin\n`path` ni `timestamp`.\n\n`code` y `details` **no** son parte del contrato general: sólo los traen los rechazos\nque los construyen explícitamente (por ejemplo `UPLOAD_REJECTED_BY_NAMESPACE` al\nreutilizar un archivo en otro namespace, o `PROVIDER_CAPACITY_EXHAUSTED` en un 429).\nNo ramifiques por `code` en el resto de las rutas: ahí no viene.\n","properties":{"statusCode":{"type":"integer","description":"Código HTTP de la respuesta.","isRequired":true,"uniqueKey":"statusCode","typeLabel":"integer"},"message":{"oneOf":[{"type":"string","description":"Mensaje legible para humanos. Es un arreglo cuando el 400 viene de la validación del body.","isRequired":true,"uniqueKey":"message.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"string","uniqueKey":"message.oneOf.1.items.[INDEX]","typeLabel":"string"},"description":"Mensaje legible para humanos. Es un arreglo cuando el 400 viene de la validación del body.","isRequired":true,"uniqueKey":"message.oneOf.1","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"message","typeLabel":"string | string[]"},"error":{"type":"string","description":"Etiqueta HTTP del estado (`Bad Request`, `Not Found`, …).","uniqueKey":"error","typeLabel":"string"},"path":{"type":"string","description":"Ruta de la petición que falló. Presente en los errores que emite el filtro global.","uniqueKey":"path","typeLabel":"string"},"timestamp":{"type":"string","format":"date-time","description":"Momento en que se generó la respuesta de error. Presente en los errores que emite el filtro global.","uniqueKey":"timestamp","typeLabel":"string\u003cdate-time>"},"code":{"type":"string","description":"Identificador estable del rechazo. Sólo en los errores que lo declaran; ausente en el resto.","uniqueKey":"code","typeLabel":"string"},"details":{"type":"object","description":"Información adicional específica del error, presente sólo cuando el rechazo la construye.\nCuando aplique, `details.subcode` provee un identificador estable para que el frontend decida qué UI mostrar.\n","properties":{"subcode":{"type":"string","description":"Identificador específico del error (p.ej. `WORKSPACE_NOT_PROVISIONED`).","uniqueKey":"details.subcode","typeLabel":"string"},"workspaceId":{"type":"string","format":"uuid","description":"Identificador de workspace relacionado cuando aplica.","uniqueKey":"details.workspaceId","typeLabel":"string\u003cuuid>"}},"additionalProperties":true,"uniqueKey":"details","typeLabel":"object"}},"required":["statusCode","message"],"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"statusCode":123,"message":"\u003cstring>","error":"\u003cstring>","path":"\u003cstring>","timestamp":"2023-11-07T05:31:56Z","code":"\u003cstring>","details":{"subcode":"\u003cstring>","workspaceId":"3c90c3cc-0d44-4b50-8888-8dd25736052a"}}}},"exampleType":"generated"}},"exampleType":"generated"},"4e4aa60c-0faf-4c7c-9ae1-54dea8d48a4f":{"description":"El carril de subida por URL prefirmada está cerrado para este workspace. El cuerpo\nes genérico a propósito: nombrar la feature delataría lo que el `404` oculta.\n","content":{"application/json":{"schema":{"type":"object","description":"Forma común de los errores de la API. El filtro global responde\n`{ statusCode, error, message, path, timestamp }`; los 400 que produce la validación del\nbody llegan con `message` como arreglo de strings (uno por regla incumplida) y sin\n`path` ni `timestamp`.\n\n`code` y `details` **no** son parte del contrato general: sólo los traen los rechazos\nque los construyen explícitamente (por ejemplo `UPLOAD_REJECTED_BY_NAMESPACE` al\nreutilizar un archivo en otro namespace, o `PROVIDER_CAPACITY_EXHAUSTED` en un 429).\nNo ramifiques por `code` en el resto de las rutas: ahí no viene.\n","properties":{"statusCode":{"type":"integer","description":"Código HTTP de la respuesta.","isRequired":true,"uniqueKey":"statusCode","typeLabel":"integer"},"message":{"oneOf":[{"type":"string","description":"Mensaje legible para humanos. Es un arreglo cuando el 400 viene de la validación del body.","isRequired":true,"uniqueKey":"message.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"string","uniqueKey":"message.oneOf.1.items.[INDEX]","typeLabel":"string"},"description":"Mensaje legible para humanos. Es un arreglo cuando el 400 viene de la validación del body.","isRequired":true,"uniqueKey":"message.oneOf.1","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"message","typeLabel":"string | string[]"},"error":{"type":"string","description":"Etiqueta HTTP del estado (`Bad Request`, `Not Found`, …).","uniqueKey":"error","typeLabel":"string"},"path":{"type":"string","description":"Ruta de la petición que falló. Presente en los errores que emite el filtro global.","uniqueKey":"path","typeLabel":"string"},"timestamp":{"type":"string","format":"date-time","description":"Momento en que se generó la respuesta de error. Presente en los errores que emite el filtro global.","uniqueKey":"timestamp","typeLabel":"string\u003cdate-time>"},"code":{"type":"string","description":"Identificador estable del rechazo. Sólo en los errores que lo declaran; ausente en el resto.","uniqueKey":"code","typeLabel":"string"},"details":{"type":"object","description":"Información adicional específica del error, presente sólo cuando el rechazo la construye.\nCuando aplique, `details.subcode` provee un identificador estable para que el frontend decida qué UI mostrar.\n","properties":{"subcode":{"type":"string","description":"Identificador específico del error (p.ej. `WORKSPACE_NOT_PROVISIONED`).","uniqueKey":"details.subcode","typeLabel":"string"},"workspaceId":{"type":"string","format":"uuid","description":"Identificador de workspace relacionado cuando aplica.","uniqueKey":"details.workspaceId","typeLabel":"string\u003cuuid>"}},"additionalProperties":true,"uniqueKey":"details","typeLabel":"object"}},"required":["statusCode","message"],"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"statusCode":123,"message":"\u003cstring>","error":"\u003cstring>","path":"\u003cstring>","timestamp":"2023-11-07T05:31:56Z","code":"\u003cstring>","details":{"subcode":"\u003cstring>","workspaceId":"3c90c3cc-0d44-4b50-8888-8dd25736052a"}}}},"exampleType":"generated"}},"exampleType":"generated"},"7ab9edc9-71f2-4827-bd4f-2725c824e756":{"description":"Un archivo pasa del `maxBytes` de su namespace, o la suma del lote pasa de su\n`maxBatchBytes`.\n","content":{"application/json":{"schema":{"type":"object","description":"Forma común de los errores de la API. El filtro global responde\n`{ statusCode, error, message, path, timestamp }`; los 400 que produce la validación del\nbody llegan con `message` como arreglo de strings (uno por regla incumplida) y sin\n`path` ni `timestamp`.\n\n`code` y `details` **no** son parte del contrato general: sólo los traen los rechazos\nque los construyen explícitamente (por ejemplo `UPLOAD_REJECTED_BY_NAMESPACE` al\nreutilizar un archivo en otro namespace, o `PROVIDER_CAPACITY_EXHAUSTED` en un 429).\nNo ramifiques por `code` en el resto de las rutas: ahí no viene.\n","properties":{"statusCode":{"type":"integer","description":"Código HTTP de la respuesta.","isRequired":true,"uniqueKey":"statusCode","typeLabel":"integer"},"message":{"oneOf":[{"type":"string","description":"Mensaje legible para humanos. Es un arreglo cuando el 400 viene de la validación del body.","isRequired":true,"uniqueKey":"message.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"string","uniqueKey":"message.oneOf.1.items.[INDEX]","typeLabel":"string"},"description":"Mensaje legible para humanos. Es un arreglo cuando el 400 viene de la validación del body.","isRequired":true,"uniqueKey":"message.oneOf.1","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"message","typeLabel":"string | string[]"},"error":{"type":"string","description":"Etiqueta HTTP del estado (`Bad Request`, `Not Found`, …).","uniqueKey":"error","typeLabel":"string"},"path":{"type":"string","description":"Ruta de la petición que falló. Presente en los errores que emite el filtro global.","uniqueKey":"path","typeLabel":"string"},"timestamp":{"type":"string","format":"date-time","description":"Momento en que se generó la respuesta de error. Presente en los errores que emite el filtro global.","uniqueKey":"timestamp","typeLabel":"string\u003cdate-time>"},"code":{"type":"string","description":"Identificador estable del rechazo. Sólo en los errores que lo declaran; ausente en el resto.","uniqueKey":"code","typeLabel":"string"},"details":{"type":"object","description":"Información adicional específica del error, presente sólo cuando el rechazo la construye.\nCuando aplique, `details.subcode` provee un identificador estable para que el frontend decida qué UI mostrar.\n","properties":{"subcode":{"type":"string","description":"Identificador específico del error (p.ej. `WORKSPACE_NOT_PROVISIONED`).","uniqueKey":"details.subcode","typeLabel":"string"},"workspaceId":{"type":"string","format":"uuid","description":"Identificador de workspace relacionado cuando aplica.","uniqueKey":"details.workspaceId","typeLabel":"string\u003cuuid>"}},"additionalProperties":true,"uniqueKey":"details","typeLabel":"object"}},"required":["statusCode","message"],"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"statusCode":123,"message":"\u003cstring>","error":"\u003cstring>","path":"\u003cstring>","timestamp":"2023-11-07T05:31:56Z","code":"\u003cstring>","details":{"subcode":"\u003cstring>","workspaceId":"3c90c3cc-0d44-4b50-8888-8dd25736052a"}}}},"exampleType":"generated"}},"exampleType":"generated"}},"security":{"8ea4ebc0-2531-4937-b95c-7a0510429de3":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","scopes":[]}},"615db291-8983-49c9-a781-a5630059c2a7":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key","description":"API key para autenticacion programatica por workspace. El workspace viaja dentro de la\npropia llave, así que con `x-api-key` no hace falta el header `x-workspace-id`.\n\nLa llave sólo autentica en el despliegue cuyo entorno coincide con el `environment` con\nel que se emitió: si no coinciden, cualquier ruta responde\n`401 API key environment mismatch` antes de mirar los scopes.\n","scopes":[]}}},"servers":{"0be97b1f-0dc6-4cbd-a6d4-29e384bd2b64":{"url":"https://api-prod.studio.getsupervisor.ai","description":"Producción"},"41f9c1e2-e079-49e6-8b36-a71dbc10245d":{"url":"https://sandbox.agents.studio.getsupervisor.ai","description":"Sandbox"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"http","scheme":"bearer","bearerFormat":"JWT","scopes":[]},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"Bearer authentication header of the form `Bearer \u003ctoken>`, where `\u003ctoken>` is your auth token.","format":"bearer","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"BearerAuth","name":"Authorization"}],"title":"BearerAuth"},{"schemes":[{"scheme":{"type":"apiKey","in":"header","name":"x-api-key","description":"API key para autenticacion programatica por workspace. El workspace viaja dentro de la\npropia llave, así que con `x-api-key` no hace falta el header `x-workspace-id`.\n\nLa llave sólo autentica en el despliegue cuyo entorno coincide con el `environment` con\nel que se emitió: si no coinciden, cualquier ruta responde\n`401 API key environment mismatch` antes de mirar los scopes.\n","scopes":[]},"schema":{"title":"x-api-key","type":"string","description":"API key para autenticacion programatica por workspace. El workspace viaja dentro de la\npropia llave, así que con `x-api-key` no hace falta el header `x-workspace-id`.\n\nLa llave sólo autentica en el despliegue cuyo entorno coincide con el `environment` con\nel que se emitió: si no coinciden, cualquier ruta responde\n`401 API key environment mismatch` antes de mirar los scopes.\n","isRequired":true,"typeLabel":"string","deprecated":false},"schemeName":"ApiKeyAuth","name":"x-api-key"}],"title":"ApiKeyAuth"}]},"originalFileLocation":"openapi/public-api.yaml"},"subdomain":"supervisorai","siteName":"Agents Studio Docs","title":"Pedir subir archivos a un destino - Agents Studio Docs","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-09-12T23:53:59.625Z","originalFileLocation":"api-reference/uploads/pedir-subir-archivos-a-un-destino.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Reserva un sitio para cada archivo y devuelve la URL con la que el cliente lo sube directamente al almacén: la API nunca ve los bytes. El namespace va en la ruta porque identifica el destino del archivo, y cada uno tiene su propia política —qué extensiones acepta, cuánto pesa como mucho cada archivo, cuántos admite una petición y qué scope exige—. Uno de los permisos lo decide ese namespace: agent-briefs pide agents:write y knowledge-sources pide knowledge-bases:write. Y hace falta además uploads:write, que es el mismo que exigen confirm y DELETE. Son dos preguntas distintas —«puedes escribir en este destino» y «puedes manejar archivos subidos»— y firmar sin la segunda dejaría pasar una petición que no va a poder cerrar el ciclo: el objeto llegaría a S3 sin forma de confirmarlo ni descartarlo. Cada archivo deja una fila creada antes de firmar, y por eso la respuesta es 201 aunque todavía no se haya subido un solo byte: esa fila es lo que hace localizable a un archivo que nunca llegue a subirse. La operación no es idempotente: dos llamadas dan dos uploadId y dos filas, y la que no se confirme caduca a las 24 h. El carril está detrás de un feature flag por workspace. Cerrado, responde 404.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Agents Studio Docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/supervisorai/pMqwuhpUCGdZ2stR/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/supervisorai/pMqwuhpUCGdZ2stR/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/supervisorai/pMqwuhpUCGdZ2stR/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/supervisorai/pMqwuhpUCGdZ2stR/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/supervisorai/pMqwuhpUCGdZ2stR/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/supervisorai/pMqwuhpUCGdZ2stR/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/supervisorai/pMqwuhpUCGdZ2stR/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/supervisorai/pMqwuhpUCGdZ2stR/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/supervisorai/pMqwuhpUCGdZ2stR/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Pedir subir archivos a un destino - Agents Studio Docs\">\u003cmeta data-mint-head property=\"og:description\" content=\"Reserva un sitio para cada archivo y devuelve la URL con la que el cliente lo sube directamente al almacén: la API nunca ve los bytes. El namespace va en la ruta porque identifica el destino del archivo, y cada uno tiene su propia política —qué extensiones acepta, cuánto pesa como mucho cada archivo, cuántos admite una petición y qué scope exige—. Uno de los permisos lo decide ese namespace: agent-briefs pide agents:write y knowledge-sources pide knowledge-bases:write. Y hace falta además uploads:write, que es el mismo que exigen confirm y DELETE. Son dos preguntas distintas —«puedes escribir en este destino» y «puedes manejar archivos subidos»— y firmar sin la segunda dejaría pasar una petición que no va a poder cerrar el ciclo: el objeto llegaría a S3 sin forma de confirmarlo ni descartarlo. Cada archivo deja una fila creada antes de firmar, y por eso la respuesta es 201 aunque todavía no se haya subido un solo byte: esa fila es lo que hace localizable a un archivo que nunca llegue a subirse. La operación no es idempotente: dos llamadas dan dos uploadId y dos filas, y la que no se confirme caduca a las 24 h. El carril está detrás de un feature flag por workspace. Cerrado, responde 404.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Agents Studio Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.getsupervisor.ai/api-reference/uploads/pedir-subir-archivos-a-un-destino\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://supervisorai.mintlify.app/_mintlify/api/og/v2?division=Uploads\u0026amp;title=Pedir+subir+archivos+a+un+destino\u0026amp;description=Reserva+un+sitio+para+cada+archivo+y+devuelve+la+URL+con+la+que+el+cliente+lo+sube%0Adirectamente+al+almac%C3%A9n%3A+la+API+nunca+ve+los+bytes.%0A%0AEl+**namespace+va+en+la+\u0026amp;theme=b935acd2f6df3922f77fb669\u0026amp;signature=68243c627b0267f16cbbf97581782f558ede0cc9d21e4737369ba6d2fa20871f\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Pedir subir archivos a un destino - Agents Studio Docs\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Reserva un sitio para cada archivo y devuelve la URL con la que el cliente lo sube directamente al almacén: la API nunca ve los bytes. El namespace va en la ruta porque identifica el destino del archivo, y cada uno tiene su propia política —qué extensiones acepta, cuánto pesa como mucho cada archivo, cuántos admite una petición y qué scope exige—. Uno de los permisos lo decide ese namespace: agent-briefs pide agents:write y knowledge-sources pide knowledge-bases:write. Y hace falta además uploads:write, que es el mismo que exigen confirm y DELETE. Son dos preguntas distintas —«puedes escribir en este destino» y «puedes manejar archivos subidos»— y firmar sin la segunda dejaría pasar una petición que no va a poder cerrar el ciclo: el objeto llegaría a S3 sin forma de confirmarlo ni descartarlo. Cada archivo deja una fila creada antes de firmar, y por eso la respuesta es 201 aunque todavía no se haya subido un solo byte: esa fila es lo que hace localizable a un archivo que nunca llegue a subirse. La operación no es idempotente: dos llamadas dan dos uploadId y dos filas, y la que no se confirme caduca a las 24 h. El carril está detrás de un feature flag por workspace. Cerrado, responde 404.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://supervisorai.mintlify.app/_mintlify/api/og/v2?division=Uploads\u0026amp;title=Pedir+subir+archivos+a+un+destino\u0026amp;description=Reserva+un+sitio+para+cada+archivo+y+devuelve+la+URL+con+la+que+el+cliente+lo+sube%0Adirectamente+al+almac%C3%A9n%3A+la+API+nunca+ve+los+bytes.%0A%0AEl+**namespace+va+en+la+\u0026amp;theme=b935acd2f6df3922f77fb669\u0026amp;signature=68243c627b0267f16cbbf97581782f558ede0cc9d21e4737369ba6d2fa20871f\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/supervisorai/pMqwuhpUCGdZ2stR/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Agents Studio Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#0ea5e9\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.getsupervisor.ai/api-reference/uploads/pedir-subir-archivos-a-un-destino\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/uploads/pedir-subir-archivos-a-un-destino.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.getsupervisor.ai/#organization\",\"name\":\"Agents Studio Docs\",\"url\":\"https://docs.getsupervisor.ai\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/supervisorai/aFOceNtmZJygjrCt/logo/leracom.png?fit=max\u0026auto=format\u0026n=aFOceNtmZJygjrCt\u0026q=85\u0026s=50cc1af96825067fbe033d98f4ba5e29\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.getsupervisor.ai#website\",\"name\":\"Agents Studio Docs\",\"url\":\"https://docs.getsupervisor.ai\",\"publisher\":{\"@id\":\"https://docs.getsupervisor.ai/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.getsupervisor.ai/api-reference/uploads/pedir-subir-archivos-a-un-destino#webpage\",\"url\":\"https://docs.getsupervisor.ai/api-reference/uploads/pedir-subir-archivos-a-un-destino\",\"name\":\"Pedir subir archivos a un destino\",\"description\":\"Reserva un sitio para cada archivo y devuelve la URL con la que el cliente lo sube directamente al almacén: la API nunca ve los bytes. El namespace va en la ruta porque identifica el destino del archivo, y cada uno tiene su propia política —qué extensiones acepta, cuánto pesa como mucho cada archivo, cuántos admite una petición y qué scope exige—. Uno de los permisos lo decide ese namespace: agent-briefs pide agents:write y knowledge-sources pide knowledge-bases:write. Y hace falta además uploads:write, que es el mismo que exigen confirm y DELETE. Son dos preguntas distintas —«puedes escribir en este destino» y «puedes manejar archivos subidos»— y firmar sin la segunda dejaría pasar una petición que no va a poder cerrar el ciclo: el objeto llegaría a S3 sin forma de confirmarlo ni descartarlo. Cada archivo deja una fila creada antes de firmar, y por eso la respuesta es 201 aunque todavía no se haya subido un solo byte: esa fila es lo que hace localizable a un archivo que nunca llegue a subirse. La operación no es idempotente: dos llamadas dan dos uploadId y dos filas, y la que no se confirme caduca a las 24 h. El carril está detrás de un feature flag por workspace. Cerrado, responde 404.\",\"dateModified\":\"2026-09-12T23:53:59.625Z\",\"isPartOf\":{\"@id\":\"https://docs.getsupervisor.ai#website\"},\"breadcrumb\":{\"@id\":\"https://docs.getsupervisor.ai/api-reference/uploads/pedir-subir-archivos-a-un-destino#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.getsupervisor.ai/api-reference/uploads/pedir-subir-archivos-a-un-destino#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Referencia de endpoints\",\"item\":\"https://docs.getsupervisor.ai/api-reference/agents/listar-agentes-del-workspace\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Pedir subir archivos a un destino\",\"item\":\"https://docs.getsupervisor.ai/api-reference/uploads/pedir-subir-archivos-a-un-destino\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.getsupervisor.ai/api-reference/uploads/pedir-subir-archivos-a-un-destino#apireference\",\"headline\":\"Pedir subir archivos a un destino\",\"name\":\"Pedir subir archivos a un destino\",\"description\":\"Reserva un sitio para cada archivo y devuelve la URL con la que el cliente lo sube directamente al almacén: la API nunca ve los bytes. El namespace va en la ruta porque identifica el destino del archivo, y cada uno tiene su propia política —qué extensiones acepta, cuánto pesa como mucho cada archivo, cuántos admite una petición y qué scope exige—. Uno de los permisos lo decide ese namespace: agent-briefs pide agents:write y knowledge-sources pide knowledge-bases:write. Y hace falta además uploads:write, que es el mismo que exigen confirm y DELETE. Son dos preguntas distintas —«puedes escribir en este destino» y «puedes manejar archivos subidos»— y firmar sin la segunda dejaría pasar una petición que no va a poder cerrar el ciclo: el objeto llegaría a S3 sin forma de confirmarlo ni descartarlo. Cada archivo deja una fila creada antes de firmar, y por eso la respuesta es 201 aunque todavía no se haya subido un solo byte: esa fila es lo que hace localizable a un archivo que nunca llegue a subirse. La operación no es idempotente: dos llamadas dan dos uploadId y dos filas, y la que no se confirme caduca a las 24 h. El carril está detrás de un feature flag por workspace. Cerrado, responde 404.\",\"url\":\"https://docs.getsupervisor.ai/api-reference/uploads/pedir-subir-archivos-a-un-destino\",\"mainEntityOfPage\":{\"@id\":\"https://docs.getsupervisor.ai/api-reference/uploads/pedir-subir-archivos-a-un-destino#webpage\"},\"dateModified\":\"2026-09-12T23:53:59.625Z\",\"publisher\":{\"@id\":\"https://docs.getsupervisor.ai/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.getsupervisor.ai#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Agents Studio Docs\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Agents Studio Docs","nav":{"global":{},"tabs":[{"tab":"Blog","pages":[{"title":"Blog","href":"/blog"}]},{"tab":"Referencia API","groups":[{"group":"Empezar","expanded":true,"pages":[{"title":"API Reference","href":"/api-reference/introduction"},{"title":"Keys","href":"/api-reference/keys"},{"title":"TypeScript SDK","href":"/api-reference/sdk"}]},{"group":"Referencia de endpoints","expanded":true,"pages":[{"group":"Agents","pages":[{"title":"Listar agentes del workspace","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/agents","href":"/api-reference/agents/listar-agentes-del-workspace"},{"title":"Crear un agente y su versión inicial","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/agents","href":"/api-reference/agents/crear-un-agente-y-su-versión-inicial"},{"title":"Crear agente a partir de una plantilla (fork de agent_version)","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/agents/from-template","href":"/api-reference/agents/crear-agente-a-partir-de-una-plantilla-fork-de-agent_version"},{"title":"Obtener detalle de un agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/agents/{agentId}","href":"/api-reference/agents/obtener-detalle-de-un-agente"},{"title":"Eliminar un agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml delete /v1/agents/{agentId}","href":"/api-reference/agents/eliminar-un-agente"},{"title":"Actualizar atributos configurables del agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml patch /v1/agents/{agentId}","href":"/api-reference/agents/actualizar-atributos-configurables-del-agente"},{"title":"Clonar un agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/agents/{agentId}/clone","href":"/api-reference/agents/clonar-un-agente"},{"title":"Reintentar el build de un agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/agents/{agentId}/rebuild","href":"/api-reference/agents/reintentar-el-build-de-un-agente"}]},{"group":"Agent Schedules","pages":[{"title":"Listar horarios configurados del agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/agents/{agentId}/schedules","href":"/api-reference/agent-schedules/listar-horarios-configurados-del-agente"},{"title":"Crear un nuevo horario para el agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/agents/{agentId}/schedules","href":"/api-reference/agent-schedules/crear-un-nuevo-horario-para-el-agente"},{"title":"Obtener detalle de un horario del agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/agents/{agentId}/schedules/{scheduleId}","href":"/api-reference/agent-schedules/obtener-detalle-de-un-horario-del-agente"},{"title":"Actualizar un horario existente del agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml put /v1/agents/{agentId}/schedules/{scheduleId}","href":"/api-reference/agent-schedules/actualizar-un-horario-existente-del-agente"},{"title":"Listar excepciones del horario configurado","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/agents/{agentId}/schedules/exceptions","href":"/api-reference/agent-schedules/listar-excepciones-del-horario-configurado"},{"title":"Crear excepción puntual del horario","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/agents/{agentId}/schedules/exceptions","href":"/api-reference/agent-schedules/crear-excepción-puntual-del-horario"},{"title":"Obtener excepción puntual del horario","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/agents/{agentId}/schedules/exceptions/{exceptionId}","href":"/api-reference/agent-schedules/obtener-excepción-puntual-del-horario"},{"title":"Eliminar excepción puntual del horario","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml delete /v1/agents/{agentId}/schedules/exceptions/{exceptionId}","href":"/api-reference/agent-schedules/eliminar-excepción-puntual-del-horario"},{"title":"Actualizar excepción puntual del horario","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml patch /v1/agents/{agentId}/schedules/exceptions/{exceptionId}","href":"/api-reference/agent-schedules/actualizar-excepción-puntual-del-horario"}]},{"group":"Agent Versions","pages":[{"title":"Listar versiones configuradas del agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/agents/{agentId}/versions","href":"/api-reference/agent-versions/listar-versiones-configuradas-del-agente"},{"title":"Crear una nueva versión del agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/agents/{agentId}/versions","href":"/api-reference/agent-versions/crear-una-nueva-versión-del-agente"},{"title":"Obtener detalle de una versión del agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/agents/{agentId}/versions/{versionId}","href":"/api-reference/agent-versions/obtener-detalle-de-una-versión-del-agente"},{"title":"Clonar una versión del agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/agents/{agentId}/versions/{versionId}/clone","href":"/api-reference/agent-versions/clonar-una-versión-del-agente"},{"title":"Publicar una versión del agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/agents/{agentId}/versions/{versionId}/publish","href":"/api-reference/agent-versions/publicar-una-versión-del-agente"},{"title":"Actualizar notas de una versión del agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml patch /v1/agents/{agentId}/versions/{versionId}/notes","href":"/api-reference/agent-versions/actualizar-notas-de-una-versión-del-agente"}]},{"group":"Campaigns","pages":[{"title":"Crear campaña para una versión específica del agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/agents/{agentId}/versions/{versionId}/campaigns","href":"/api-reference/campaigns/crear-campaña-para-una-versión-específica-del-agente"},{"title":"Listar campañas masivas","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/campaigns","href":"/api-reference/campaigns/listar-campañas-masivas"},{"title":"Obtener detalle de una campaña","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/campaigns/{campaignId}","href":"/api-reference/campaigns/obtener-detalle-de-una-campaña"},{"title":"Listar ejecuciones individuales de una campaña","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/campaigns/{campaignId}/executions","href":"/api-reference/campaigns/listar-ejecuciones-individuales-de-una-campaña"},{"title":"Exportar ejecuciones de una campaña a CSV","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/campaigns/{campaignId}/executions/export","href":"/api-reference/campaigns/exportar-ejecuciones-de-una-campaña-a-csv"},{"title":"Pausar una campaña en curso","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/campaigns/{campaignId}/pause","href":"/api-reference/campaigns/pausar-una-campaña-en-curso"},{"title":"Reanudar una campaña pausada","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/campaigns/{campaignId}/resume","href":"/api-reference/campaigns/reanudar-una-campaña-pausada"},{"title":"Cancelar una campaña","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/campaigns/{campaignId}/cancel","href":"/api-reference/campaigns/cancelar-una-campaña"}]},{"group":"Agent Instructions","pages":[{"title":"Listar instrucciones de una versión del agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/agents/{agentId}/versions/{versionId}/instructions","href":"/api-reference/agent-instructions/listar-instrucciones-de-una-versión-del-agente"},{"title":"Agregar una instrucción a la versión del agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/agents/{agentId}/versions/{versionId}/instructions","href":"/api-reference/agent-instructions/agregar-una-instrucción-a-la-versión-del-agente"},{"title":"Eliminar una instrucción","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml delete /v1/agents/{agentId}/versions/{versionId}/instructions/{instructionId}","href":"/api-reference/agent-instructions/eliminar-una-instrucción"},{"title":"Editar una instrucción existente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml patch /v1/agents/{agentId}/versions/{versionId}/instructions/{instructionId}","href":"/api-reference/agent-instructions/editar-una-instrucción-existente"}]},{"group":"Agent Blueprints","pages":[{"title":"Obtener blueprint de una versión del agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/agents/{agentId}/versions/{versionId}/blueprint","href":"/api-reference/agent-blueprints/obtener-blueprint-de-una-versión-del-agente"},{"title":"Crear blueprint para una versión del agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/agents/{agentId}/versions/{versionId}/blueprint","href":"/api-reference/agent-blueprints/crear-blueprint-para-una-versión-del-agente"},{"title":"Actualizar blueprint de una versión del agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml patch /v1/agents/{agentId}/versions/{versionId}/blueprint","href":"/api-reference/agent-blueprints/actualizar-blueprint-de-una-versión-del-agente"},{"title":"Listar blueprints asociados al agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/agents/{agentId}/blueprints","href":"/api-reference/agent-blueprints/listar-blueprints-asociados-al-agente"}]},{"group":"Blueprint Stages","pages":[{"title":"Listar stages de un blueprint del agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/agents/{agentId}/blueprints/{blueprintId}/stages","href":"/api-reference/blueprint-stages/listar-stages-de-un-blueprint-del-agente"},{"title":"Crear un stage dentro del blueprint del agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/agents/{agentId}/blueprints/{blueprintId}/stages","href":"/api-reference/blueprint-stages/crear-un-stage-dentro-del-blueprint-del-agente"},{"title":"Obtener detalle de un stage específico","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/agents/{agentId}/blueprints/{blueprintId}/stages/{stageId}","href":"/api-reference/blueprint-stages/obtener-detalle-de-un-stage-específico"},{"title":"Eliminar un stage del blueprint","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml delete /v1/agents/{agentId}/blueprints/{blueprintId}/stages/{stageId}","href":"/api-reference/blueprint-stages/eliminar-un-stage-del-blueprint"},{"title":"Actualizar un stage existente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml patch /v1/agents/{agentId}/blueprints/{blueprintId}/stages/{stageId}","href":"/api-reference/blueprint-stages/actualizar-un-stage-existente"},{"title":"Reordenar los stages del blueprint","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/agents/{agentId}/blueprints/{blueprintId}/stages:reorder","href":"/api-reference/blueprint-stages/reordenar-los-stages-del-blueprint"}]},{"group":"Stage Triggers","pages":[{"title":"Listar triggers de un stage","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/agents/{agentId}/blueprints/{blueprintId}/stages/{stageId}/triggers","href":"/api-reference/stage-triggers/listar-triggers-de-un-stage"},{"title":"Crear trigger para un stage","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/agents/{agentId}/blueprints/{blueprintId}/stages/{stageId}/triggers","href":"/api-reference/stage-triggers/crear-trigger-para-un-stage"},{"title":"Obtener detalle de un trigger","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/agents/{agentId}/blueprints/{blueprintId}/stages/{stageId}/triggers/{triggerId}","href":"/api-reference/stage-triggers/obtener-detalle-de-un-trigger"},{"title":"Eliminar un trigger del stage","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml delete /v1/agents/{agentId}/blueprints/{blueprintId}/stages/{stageId}/triggers/{triggerId}","href":"/api-reference/stage-triggers/eliminar-un-trigger-del-stage"},{"title":"Actualizar un trigger existente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml patch /v1/agents/{agentId}/blueprints/{blueprintId}/stages/{stageId}/triggers/{triggerId}","href":"/api-reference/stage-triggers/actualizar-un-trigger-existente"}]},{"group":"Agent Phones","pages":[{"title":"Conectar un teléfono a un agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/agents/{agentId}/phones","href":"/api-reference/agent-phones/conectar-un-teléfono-a-un-agente"},{"title":"Desconectar un teléfono del agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml delete /v1/agents/{agentId}/phones/{phoneId}","href":"/api-reference/agent-phones/desconectar-un-teléfono-del-agente"},{"title":"Listar teléfonos disponibles del workspace","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/workspaces/{workspaceId}/phones","href":"/api-reference/agent-phones/listar-teléfonos-disponibles-del-workspace"}]},{"group":"Documents","pages":[{"title":"Crear slots de subida de documentos","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/documents","href":"/api-reference/documents/crear-slots-de-subida-de-documentos"}]},{"group":"API Keys","pages":[{"title":"Listar API Keys activas del usuario","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/api-keys","href":"/api-reference/api-keys/listar-api-keys-activas-del-usuario"},{"title":"Crear una API Key","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/api-keys","href":"/api-reference/api-keys/crear-una-api-key"},{"title":"Revocar una API Key","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml delete /v1/api-keys/{apiKeyId}","href":"/api-reference/api-keys/revocar-una-api-key"},{"title":"Mostrar valor completo de una API Key","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/api-keys/{apiKeyId}/show","href":"/api-reference/api-keys/mostrar-valor-completo-de-una-api-key"}]},{"group":"Workspaces","pages":[{"title":"Listar workspaces usando caché local","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/workspaces","href":"/api-reference/workspaces/listar-workspaces-usando-caché-local"},{"title":"Crear un workspace para el usuario autenticado","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/workspaces","href":"/api-reference/workspaces/crear-un-workspace-para-el-usuario-autenticado"},{"title":"Habilitar un workspace (API key, teléfono y Speech Analytics)","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/workspaces/enable","href":"/api-reference/workspaces/habilitar-un-workspace-api-key-teléfono-y-speech-analytics"}]},{"group":"Tools","pages":[{"title":"Listar catálogo de tools disponibles","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/tools","href":"/api-reference/tools/listar-catálogo-de-tools-disponibles"},{"title":"Ejecutar una acción de la tool para el agente indicado","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/tools/{toolId}/execute","href":"/api-reference/tools/ejecutar-una-acción-de-la-tool-para-el-agente-indicado"},{"title":"Crear una conexión entre un agente y la tool indicada","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/tools/{toolId}/connections","href":"/api-reference/tools/crear-una-conexión-entre-un-agente-y-la-tool-indicada"},{"title":"Listar conexiones entre agentes y tools","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/tools/connections","href":"/api-reference/tools/listar-conexiones-entre-agentes-y-tools"},{"title":"Crear una conexión entre un agente y una tool (por body)","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/tools/connections","href":"/api-reference/tools/crear-una-conexión-entre-un-agente-y-una-tool-por-body"},{"title":"Eliminar (desinstalar) una conexión entre un agente y una tool","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml delete /v1/tools/connections/{toolAgentConnectionId}","href":"/api-reference/tools/eliminar-desinstalar-una-conexión-entre-un-agente-y-una-tool"},{"title":"Ejecutar una acción de una tool usando el toolAgentConnectionId","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/tools/connections/{toolAgentConnectionId}/execute","href":"/api-reference/tools/ejecutar-una-acción-de-una-tool-usando-el-toolagentconnectionid"}]},{"group":"Catalogs","pages":[{"title":"Listar ítems de catálogo","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/catalogs/items","href":"/api-reference/catalogs/listar-ítems-de-catálogo"},{"title":"Crear ítem de catálogo","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/catalogs/items","href":"/api-reference/catalogs/crear-ítem-de-catálogo"},{"title":"Obtener detalle de un ítem de catálogo","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/catalogs/items/{itemId}","href":"/api-reference/catalogs/obtener-detalle-de-un-ítem-de-catálogo"},{"title":"Eliminar (soft delete) un ítem de catálogo","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml delete /v1/catalogs/items/{itemId}","href":"/api-reference/catalogs/eliminar-soft-delete-un-ítem-de-catálogo"}]},{"group":"Catalog Templates","pages":[{"title":"Listar plantillas de agente publicadas","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/catalogs/templates","href":"/api-reference/catalog-templates/listar-plantillas-de-agente-publicadas"},{"title":"Obtener detalle de una plantilla de agente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/catalogs/templates/{templateId}","href":"/api-reference/catalog-templates/obtener-detalle-de-una-plantilla-de-agente"}]},{"group":"Calls","pages":[{"title":"Listar llamadas","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/calls","href":"/api-reference/calls/listar-llamadas"},{"title":"Stream de llamadas","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/calls/stream","href":"/api-reference/calls/stream-de-llamadas"},{"title":"Obtener llamada por id","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/calls/{callId}","href":"/api-reference/calls/obtener-llamada-por-id"}]},{"group":"Webhooks","pages":[{"title":"Listar webhooks del workspace","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/webhooks","href":"/api-reference/webhooks/listar-webhooks-del-workspace"},{"title":"Crear webhook","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/webhooks","href":"/api-reference/webhooks/crear-webhook"},{"title":"Obtener detalle de webhook","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/webhooks/{webhookId}","href":"/api-reference/webhooks/obtener-detalle-de-webhook"},{"title":"Eliminar webhook (soft-delete)","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml delete /v1/webhooks/{webhookId}","href":"/api-reference/webhooks/eliminar-webhook-soft-delete"},{"title":"Actualizar webhook","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml patch /v1/webhooks/{webhookId}","href":"/api-reference/webhooks/actualizar-webhook"},{"title":"Listar suscripciones de un webhook","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/webhooks/{webhookId}/subscriptions","href":"/api-reference/webhooks/listar-suscripciones-de-un-webhook"},{"title":"Crear suscripción de evento para un webhook","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/webhooks/{webhookId}/subscriptions","href":"/api-reference/webhooks/crear-suscripción-de-evento-para-un-webhook"},{"title":"Obtener detalle de una suscripción","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/webhooks/{webhookId}/subscriptions/{subscriptionId}","href":"/api-reference/webhooks/obtener-detalle-de-una-suscripción"},{"title":"Eliminar suscripción","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml delete /v1/webhooks/{webhookId}/subscriptions/{subscriptionId}","href":"/api-reference/webhooks/eliminar-suscripción"},{"title":"Actualizar suscripción","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml patch /v1/webhooks/{webhookId}/subscriptions/{subscriptionId}","href":"/api-reference/webhooks/actualizar-suscripción"},{"title":"Listar deliveries de un webhook","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/webhooks/{webhookId}/deliveries","href":"/api-reference/webhooks/listar-deliveries-de-un-webhook"},{"title":"Obtener delivery por ID","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/webhooks/{webhookId}/deliveries/{deliveryId}","href":"/api-reference/webhooks/obtener-delivery-por-id"}]},{"group":"SIP Trunks","pages":[{"title":"Listar SIP trunks","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/sip/trunks","href":"/api-reference/sip-trunks/listar-sip-trunks"},{"title":"Crear un SIP trunk","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/sip/trunks","href":"/api-reference/sip-trunks/crear-un-sip-trunk"},{"title":"Obtener un SIP trunk por ID","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/sip/trunks/{trunkId}","href":"/api-reference/sip-trunks/obtener-un-sip-trunk-por-id"},{"title":"Eliminar un SIP trunk","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml delete /v1/sip/trunks/{trunkId}","href":"/api-reference/sip-trunks/eliminar-un-sip-trunk"},{"title":"Actualizar un SIP trunk","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml patch /v1/sip/trunks/{trunkId}","href":"/api-reference/sip-trunks/actualizar-un-sip-trunk"}]},{"group":"Message Templates","pages":[{"title":"Verificar conexión WhatsApp","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/message-templates/connection","href":"/api-reference/message-templates/verificar-conexión-whatsapp"},{"title":"Listar message templates del workspace","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/message-templates","href":"/api-reference/message-templates/listar-message-templates-del-workspace"},{"title":"Crear un message template","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/message-templates","href":"/api-reference/message-templates/crear-un-message-template"},{"title":"Eliminar un message template","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml delete /v1/message-templates/{id}","href":"/api-reference/message-templates/eliminar-un-message-template"}]},{"group":"Billing","pages":[{"title":"Obtener balance de consumo","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/billing/balance","href":"/api-reference/billing/obtener-balance-de-consumo"}]},{"group":"Usage","pages":[{"title":"Listar consumo por agente","description":"Obtiene un listado paginado del consumo agregado por agente para el workspace activo.\nLos resultados están ordenados por cantidad total consumida (descendente) e incluyen\nel porcentaje de participación de cada agente sobre el total.\n\n**El rango se acota con `filter`**, no con parámetros de fecha propios: la ruta sólo\nacepta `page`, `limit` y `filter`, y cualquier otro parámetro de consulta se responde\ncon 400. Para cuadrar un mes se filtra por `createdAt`:\n\n```\nGET /v1/usage/agents?filter=and(mte(createdAt,\"2026-03-01\"),lt(createdAt,\"2026-04-01\"))\n```\n\nCampos filtrables: `id`, `workspaceId`, `resource`, `action`, `effect`, `createdAt`,\n`entityType`, `entityId`. El listado ya viene acotado al workspace activo y a los\nregistros de tipo agente.\n","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/usage/agents","href":"/api-reference/usage/listar-consumo-por-agente"}]},{"group":"Uploads","pages":[{"title":"Pedir subir archivos a un destino","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/uploads/{namespace}","href":"/api-reference/uploads/pedir-subir-archivos-a-un-destino"},{"title":"Confirmar que el archivo ya está subido","description":"Cierra el ciclo que abrió el presign: la API va al almacén, **mira los bytes** y decide\nsi el archivo vale. Hasta que esto ocurre, lo subido no es utilizable por nadie.\n\nComprueba dos cosas que el cliente no puede acreditar por sí mismo: cuánto ocupa el\nobjeto de verdad —de ahí que `sizeBytes` pueda no coincidir con `declaredSizeBytes`—, y\nque su **contenido** corresponde a su extensión. Un `.pdf` que no empieza por `%PDF` se\nrechaza aunque el nombre diga otra cosa.\n\nEs **idempotente sobre lo que salió bien**: confirmar un archivo que ya está `ready`\ndevuelve `200` con el mismo cuerpo y no vuelve a tocar el almacén. Lo es a propósito,\nporque el cliente reintenta esta llamada cuando la red le falla a mitad.\n\nEsa red de seguridad **no cubre el rechazo**. Un `rejected` es terminal: no admite un\nsegundo `confirm`, así que si el `422` se perdió por el camino, el reintento no vuelve a\ndártelo. Para saber cómo acabó una subida cuyo `confirm` no llegó a contestar, usa el\n`GET`, que responde el estado y el `rejectedReason`.\n\nUn rechazo **se persiste antes de responder**: el archivo queda en `rejected` con su\n`rejectedReason`, no se pierde el motivo. Por eso responde `422` y no `400` — la\npetición era válida; lo que no valía era el contenido.\n","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/uploads/{uploadId}/confirm","href":"/api-reference/uploads/confirmar-que-el-archivo-ya-está-subido"},{"title":"Usar un archivo ya subido también en otro destino","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/uploads/{namespace}/from/{uploadId}","href":"/api-reference/uploads/usar-un-archivo-ya-subido-también-en-otro-destino"},{"title":"Consultar una subida","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/uploads/{uploadId}","href":"/api-reference/uploads/consultar-una-subida"},{"title":"Descartar una subida","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml delete /v1/uploads/{uploadId}","href":"/api-reference/uploads/descartar-una-subida"}]},{"group":"Health","pages":[{"title":"Verificar disponibilidad del servicio","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/health","href":"/api-reference/health/verificar-disponibilidad-del-servicio"}]},{"group":"Knowledge Bases","pages":[{"title":"Listar las bases de conocimiento del workspace","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/knowledge-bases","href":"/api-reference/knowledge-bases/listar-las-bases-de-conocimiento-del-workspace"},{"title":"Dar de alta una base de conocimiento","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/knowledge-bases","href":"/api-reference/knowledge-bases/dar-de-alta-una-base-de-conocimiento"},{"title":"Consultar una base de conocimiento y sus documentos","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/knowledge-bases/{knowledgeBaseId}","href":"/api-reference/knowledge-bases/consultar-una-base-de-conocimiento-y-sus-documentos"},{"title":"Dar de baja una base de conocimiento","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml delete /v1/knowledge-bases/{knowledgeBaseId}","href":"/api-reference/knowledge-bases/dar-de-baja-una-base-de-conocimiento"},{"title":"Qué agentes consultan una base de conocimiento","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml get /v1/knowledge-bases/{knowledgeBaseId}/agents","href":"/api-reference/knowledge-bases/qué-agentes-consultan-una-base-de-conocimiento"},{"title":"Añadir documentos a una base existente","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml post /v1/knowledge-bases/{knowledgeBaseId}/documents","href":"/api-reference/knowledge-bases/añadir-documentos-a-una-base-existente"},{"title":"Quitar un documento de una base","deprecated":null,"version":null,"openapi":"/openapi/public-api.yaml delete /v1/knowledge-bases/{knowledgeBaseId}/documents/{documentId}","href":"/api-reference/knowledge-bases/quitar-un-documento-de-una-base"}]}]},{"group":"Agentes","expanded":true,"pages":[{"title":"Plantillas de agentes","openapi":"POST /v1/agents/from-template","href":"/api-reference/endpoint/templates"},{"title":"Stages y triggers","href":"/api-reference/endpoint/stages"},{"title":"Voces disponibles","href":"/api-reference/catalogs/voices"}]},{"group":"Herramientas del agente","expanded":true,"pages":[{"title":"Tools","href":"/api-reference/endpoint/tools"},{"title":"Agendar y gestionar citas (Cal.com)","href":"/api-reference/tools/cal-com"},{"title":"Función personalizada","href":"/api-reference/tools/custom-function"},{"title":"Geocoding","href":"/api-reference/tools/geocoding"}]},{"group":"Telefonía","expanded":true,"pages":[{"title":"Iniciar llamada","href":"/api-reference/endpoint/phone-call"},{"title":"Agendar llamada","href":"/api-reference/telephony/schedule-call"},{"title":"Calls","href":"/api-reference/endpoint/calls"},{"title":"Campaigns","href":"/api-reference/endpoint/campaigns"}]},{"group":"Webhooks","expanded":true,"pages":[{"title":"Webhooks","href":"/api-reference/endpoint/webhook"},{"title":"Notificaciones de llamada","href":"/api-reference/endpoint/notifications"}]},{"group":"MCP","expanded":true,"pages":[{"title":"MCP server","href":"/api-reference/mcp"}]}]}]},"title":"Pedir subir archivos a un destino - Agents Studio Docs","buildId":"dpl_DFJrtvUi8HS5F9nkooKuDJsuD5BM","deploymentId":"dpl_DFJrtvUi8HS5F9nkooKuDJsuD5BM","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-rfhihCWU.js","utils-BmH1XFxk.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-BcNsxPKB.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-BAES3tkd.js","snippetPresets-DCMQBKLP.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","ApiExamples-D6l_bzE9.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-BOktbnNh.js","shallow-BCs8SgM7.js","getApiPlaygroundDisplay-DEmW5bJB.js","CodeSnippet-CpZOpB9C.js","CodeSnippets-BOBDqibl.js","Page-D5fEM6aW.js","getPastedJson-DH2JBvmr.js","icon-BBJH-kKh.js","MethodPill-D2Sd5NLC.js","DuplicateIcon-CGgfL2qN.js","createIcon-BKudBBzi.js","DynamicMarkdown-85clUA0i.js","SectionHeading-D0JiMgDx.js","axios-vUo_bRtp.js","Markdown-Cfiy0xZO.js","clsx-rL8ZCCw4.js","lib--scc4DXi.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-aeztFa9U.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-BywkCr5C.js"]}