| Location | Name | Required | Meaning |
|---|---|---|---|
| path | sub | Yes | Use the ID from an authorized staff response; source validators reject malformed IDs. |
| path | id | Yes | Use the ID from an authorized staff response; source validators reject malformed IDs. |
| query | content | Conditional / optional | Requests unmasked titles, names, settings and emails. Requires owner/support, fresh step-up and audit. Never returns document text or file/audio bytes. |
| header | X-Admin-Reason | Conditional / optional | URI-encoded written audit reason; Cloud/billing may reuse a fresh target-specific session marker. |
{error:{code,message}} for CloudError failures, attaches Request-Id, and disables caching. Handle 401 by signing in; show role refusal for 403 forbidden, reauthenticate only for step_up_required, and collect a reason for 400 reason_required. A CSRF failure needs a current page/session token, not blind retries. Operation-specific 404/409/413/422/502/503 errors retain their status. Honor Retry-After on 429./**
* GET /api/admin/accounts/:sub/cloud/documents/:id[?content=1]: one document the account owns, with its shares,
* pending invitations, audio render counts and search index presence. Documents owned by anyone else are 404 here
* (the unlock covers this account only). Never the text, the file or audio.
*/
export const GET = cloudRoute<{ sub: string; id: string }>("document", accountTarget, async (_request, { viewer, params }) => {
if (!isDocumentId(params.id)) throw notFound();
const detail = await documentDetail(params.id);
if (!detail || detail.document.owner !== accountPrincipal(params.sub)) throw notFound();
return presentDocumentDetail(detail, viewer);
});