langfuse/langfuse · error · ForbiddenError
Forbidden
Error message
Forbidden
What it means
GET /api/public/media/:mediaId requires a project-scoped API key; requests authenticated with org-level keys or Bearer PATs get a bare 403 Forbidden before the media lookup.
Source
Thrown at web/src/pages/api/public/media/[mediaId].ts:22
getMedia,
updateMediaUploadStatus,
} from "@/src/features/media/server/mediaService";
import {
GetMediaQuerySchema,
GetMediaResponseSchema,
PatchMediaBodySchema,
} from "@/src/features/media/validation";
import { createAuthedProjectAPIRoute } from "@/src/features/public-api/server/createAuthedProjectAPIRoute";
import { withMiddlewares } from "@/src/features/public-api/server/withMiddlewares";
import { ForbiddenError } from "@langfuse/shared";
export default withMiddlewares({
GET: createAuthedProjectAPIRoute({
name: "Get Media data",
querySchema: GetMediaQuerySchema,
responseSchema: GetMediaResponseSchema,
fn: async ({ query, auth }) => {
if (auth.scope.accessLevel !== "project") throw new ForbiddenError();
const { projectId } = auth.scope;
const { mediaId } = query;
return await getMedia({ projectId, mediaId });
},
}),
PATCH: createAuthedProjectAPIRoute({
name: "Update Media Uploaded At",
querySchema: z.object({
mediaId: z.string(),
}),
bodySchema: PatchMediaBodySchema,
responseSchema: z.void(),
rateLimitResource: "media-upload",
fn: async ({ query, body, auth }) => {
if (auth.scope.accessLevel !== "project") throw new ForbiddenError();View on GitHub (pinned to 59d92c7cf3)
Solutions
- Use a project-scoped API key with Basic auth for media endpoints
Defensive patterns
Strategy: validation
Validate before calling
if (publicKey.startsWith('org-')) throw new Error('media endpoints need a project key'); Prevention
- Use dedicated project keys for ingestion/media flows
When it happens
Trigger: Calling the media GET endpoint with an organization API key or Bearer token instead of a project pk/sk pair.
Common situations: Scripts that reuse one org key for all public API calls; PAT-based automation hitting project-only endpoints.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Forbidden
- Access denied: MCP requires project-scoped API keys with Bas
- windowMs ${ms.toString()} does not correspond to a known Mon
- Invalid relationTable for entity dimension ${field}: ${dimen
- invalid-request
AI-assisted analysis of langfuse/langfuse@59d92c7cf3 (2026-08-27).
Data as JSON: /api/errors/4f32b20b5fdceb33.
Report an issue: GitHub.