---
title: "Get Project"
method: GET
path: "/api/projects/{project_id}"
---

# Get Project

`GET /api/projects/{project_id}`

Get project details

Sync endpoint on purpose: it does blocking SQLAlchemy I/O, so FastAPI must
run it in the threadpool. As `async def` it froze the event loop (and the
/health endpoint with it) for the whole request.

Args:
    project_id: Project ID
    current_user: Authenticated user
    db: Database session
    
Returns:
    GetProjectResponse with full project details

## Path parameters

- `project_id` string, required

## Response `200`

Successful Response

- GetProjectResponse — Response schema for getting a project
  - `success` boolean
  - `project` ProjectResponse, required — Response schema for project
    - `id` string, required
    - `projectId` string, required
    - `userId` string, required
    - `organizationId` string, nullable
    - `name` string, required
    - `prompt` string, required
    - `status` string, required
    - `sessionId` string, nullable
    - `planText` string, nullable
    - `metadata` ProjectMetadata, required — Project metadata schema
      - `title` string, nullable
      - `style` string, nullable
      - `motionGraphicsStyle` string, nullable
      - `aspectRatio` string, nullable
      - `length` integer, nullable
      - `voiceover` boolean, nullable
    - `videos` VideoResponse[] — Videos directly owned by project (video-centric timeline)
      - `id` string, required
      - `projectId` string, nullable
      - `sceneId` string, nullable
      - `orderIndex` integer
      - `name` string, nullable — Optional name for the video
      - `description` string, nullable — Visual description of the video
      - `status` string — Generation status: pending, generating, completed, failed, dismissed
      - `errorMessage` string, nullable — Persisted generation failure reason
      - `voiceover` string, nullable — Voiceover text for this video
      - `volume` integer — Volume level 0-200 (percentage)
      - `sourceCode` string, nullable — Source code snapshot for generated/editable videos
      - `workspaceArchiveUrl` string, nullable — Durable workspace archive URL for generated/editable videos
      - `workspaceArchiveSha256` string, nullable
      - `workspaceArchiveSizeBytes` integer, nullable
      - `workspaceArchiveCreatedAt` string, date-time, nullable
      - `videoUrl` string, nullable
      - `baseVideoUrl` string, nullable
      - `captionStyles` object, nullable
      - `hlsUrl` string, nullable
      - `model` string, required
      - `prompt` string, nullable
      - `duration` integer, required
      - `playbackSpeed` number
      - `cropStartMs` integer — Milliseconds trimmed from start (soft crop)
      - `cropEndMs` integer — Milliseconds trimmed from end (soft crop)
      - `startKeyframeId` string, nullable
      - `endKeyframeId` string, nullable
      - `lipSyncAudioClipId` string, nullable
      - `elements` object — Per-video element references (e.g., {startKeyframeID,prompt[,endKeyframeID]})
      - `audioClips` AudioClipResponse[]
        - `id` string, required
        - `sceneId` string, nullable
        - `videoId` string, nullable
        - `name` string, nullable
        - `audioUrl` string, required
        - `startTimestamp` integer, required
        - `trimStartMs` integer — Milliseconds trimmed from start of the source audio (in-point offset)
        - `volume` integer — Volume level 0-200 (percentage)
        - `speed` number — Playback speed multiplier (0.5-2.0)
        - `sourceDurationMs` integer — Original source audio duration in milliseconds (read-only)
        - `clipType` string, nullable
        - `prompt` string, nullable
        - `voiceId` string, nullable
        - `duration` integer, nullable
        - `isLoop` boolean — When true, allows extending duration beyond source by looping
        - `fileFormat` string, nullable
        - `fileSize` integer, nullable
        - `createdAt` string, date-time, required
        - `updatedAt` string, date-time, required
      - `modelId` string, nullable — FK to models(id)
      - `prompts` object[], nullable — [{prompt_str, duration}, ...]
      - `imageRefs` object[], nullable — [{image_id, type}, ...]
      - `videoRefs` object[], nullable — Source video refs (v2v, motion-control, remix); each entry is {id, role}
      - `assetRefs` string[], nullable — Ids of asset overlays / elements
      - `generationParams` object, nullable — Model-specific knobs
      - `createdAt` string, date-time, required
      - `updatedAt` string, date-time, required
      - `activeVersionNumber` integer
      - `versions` VideoVersionResponse[]
        - `id` string, required
        - `versionNumber` integer, required
        - `parentVersionId` string, nullable
        - `createdAt` string, date-time, nullable
        - `isActive` boolean
        - `previewUrl` string, nullable
        - `videoUrl` string, nullable
        - `hlsUrl` string, nullable
        - `prompt` string, nullable
        - `model` string, nullable
        - `duration` integer, nullable
        - `status` string, nullable
        - `errorMessage` string, nullable
        - `description` string, nullable
        - `voiceover` string, nullable
        - `volume` integer, nullable
        - `sourceCode` string, nullable
        - `workspaceArchiveUrl` string, nullable
        - `workspaceArchiveSha256` string, nullable
        - `workspaceArchiveSizeBytes` integer, nullable
        - `workspaceArchiveCreatedAt` string, date-time, nullable
        - `playbackSpeed` number
        - `cropStartMs` integer
        - `cropEndMs` integer
        - `orderIndex` integer
        - `startKeyframeId` string, nullable
        - `endKeyframeId` string, nullable
        - `lipSyncAudioClipId` string, nullable
        - `elements` object
        - `associatedKeyframes` object[]
    - `keyframes` KeyframeResponse[] — Keyframes directly owned by project
      - `id` string, required
      - `projectId` string, nullable — Project-level ownership (primary)
      - `sceneId` string, nullable — DEPRECATED: kept for backward compatibility
      - `keyframeUrl` string, required
      - `prompt` string, nullable — Prompt used to generate this keyframe
      - `imageWidth` integer, nullable
      - `imageHeight` integer, nullable
      - `imageFormat` string, nullable
      - `imageSize` integer, nullable
      - `aspectRatio` string, nullable
      - `createdAt` string, date-time, required
      - `updatedAt` string, date-time, required
      - `assets` AssetResponse[]
        - `id` string, required
        - `projectId` string, required
        - `parentAssetId` string, nullable
        - `sceneId` string, nullable
        - `keyframeId` string, nullable
        - `name` string, required
        - `prompt` string, nullable
        - `mediaType` 'image' | 'video' | 'audio'
        - `imageUrl` string, nullable
        - `imageId` string, nullable
        - `videoUrl` string, nullable
        - `audioUrl` string, nullable
        - `durationMs` integer, nullable
        - `primaryVideoId` string, nullable
        - `primaryAudioClipId` string, nullable
        - `primaryImageId` string, nullable
        - `secondaryImageIds` object, nullable
        - `hasMultipleAngles` boolean
        - `secondaryAngles` object, nullable
        - `versions` AssetVersionResponse[]
          - `id` string, required
          - `versionNumber` integer, required
          - `parentVersionId` string, nullable
          - `createdAt` string, date-time, nullable
          - `isActive` boolean
          - `thumbnailUrl` string, nullable
          - `imageUrl` string, nullable
          - `name` string, nullable
          - `prompt` string, nullable
        - `activeVersionNumber` integer
        - `createdAt` string, date-time, required
        - `updatedAt` string, date-time, required
        - `subAssets` AssetResponse[]
      - `activeVersionNumber` integer
      - `versions` KeyframeVersionResponse[]
        - `id` string, required
        - `versionNumber` integer, required
        - `parentVersionId` string, nullable
        - `createdAt` string, date-time, nullable
        - `isActive` boolean
        - `thumbnailUrl` string, nullable
        - `keyframeUrl` string, nullable
        - `prompt` string, nullable
        - `imageWidth` integer, nullable
        - `imageHeight` integer, nullable
        - `imageFormat` string, nullable
        - `imageSize` integer, nullable
        - `aspectRatio` string, nullable
        - `assetIds` string[]
      - `imageId` string, nullable
      - `modelId` string, nullable
      - `sourceImageIds` string[], nullable
      - `isUserUploaded` boolean, nullable
    - `audioClips` AudioClipResponse[] — Audio clips directly owned by project
      - `id` string, required
      - `sceneId` string, nullable
      - `videoId` string, nullable
      - `name` string, nullable
      - `audioUrl` string, required
      - `startTimestamp` integer, required
      - `trimStartMs` integer — Milliseconds trimmed from start of the source audio (in-point offset)
      - `volume` integer — Volume level 0-200 (percentage)
      - `speed` number — Playback speed multiplier (0.5-2.0)
      - `sourceDurationMs` integer — Original source audio duration in milliseconds (read-only)
      - `clipType` string, nullable
      - `prompt` string, nullable
      - `voiceId` string, nullable
      - `duration` integer, nullable
      - `isLoop` boolean — When true, allows extending duration beyond source by looping
      - `fileFormat` string, nullable
      - `fileSize` integer, nullable
      - `createdAt` string, date-time, required
      - `updatedAt` string, date-time, required
    - `overlayClips` OverlayClipResponse[] — Overlay/B-roll video clips on the project timeline
      - `id` string, required
      - `projectId` string, required
      - `videoId` string, nullable
      - `startMs` integer
      - `durationMs` integer, required
      - `sourceDurationMs` integer
      - `trimStartMs` integer
      - `opacity` number
      - `zIndex` integer
      - `model` string, nullable
      - `elements` object, nullable
      - `sourceVideoId` string, nullable
      - `versions` unknown[]
        - unknown
      - `activeVersionNumber` integer
      - `createdAt` string, date-time, required
      - `updatedAt` string, date-time, required
    - `scenes` SceneResponse[] — DEPRECATED: use videos/keyframes instead
      - `id` string, required
      - `projectId` string, required
      - `name` string, required
      - `description` string, required
      - `status` string, nullable
      - `type` string, nullable — Scene type: 'cinematic-video' or 'motion-graphic'
      - `requiresApproval` boolean, required
      - `videoUrl` string, nullable
      - `keyframeUrl` string, nullable
      - `duration` integer, nullable — Duration in ms. None = dynamic (determined by voiceover)
      - `cropStartMs` integer, nullable — Milliseconds trimmed from start (soft crop)
      - `cropEndMs` integer, nullable — Milliseconds trimmed from end (soft crop)
      - `order` integer, required
      - `voiceover` string, nullable — Voiceover text for the scene
      - `volume` integer — Volume level 0-200 (percentage)
      - `videoWidth` integer, nullable
      - `videoHeight` integer, nullable
      - `videoFormat` string, nullable
      - `videoSize` integer, nullable
      - `llmXml` string, nullable
      - `elementSequence` ElementSequence — Schema for the complete element sequence
        - `elements` ElementSequenceItem[] — Ordered list of elements
          - `type` string, required — Element type: 'keyframe' or 'video'
          - `id` string, required — UUID of the keyframe or video
          - `startTime` integer — Start time relative to previous element (ms)
          - `duration` integer, nullable — Duration in milliseconds (null for keyframes)
      - `audioClips` AudioClipResponse[]
        - `id` string, required
        - `sceneId` string, nullable
        - `videoId` string, nullable
        - `name` string, nullable
        - `audioUrl` string, required
        - `startTimestamp` integer, required
        - `trimStartMs` integer — Milliseconds trimmed from start of the source audio (in-point offset)
        - `volume` integer — Volume level 0-200 (percentage)
        - `speed` number — Playback speed multiplier (0.5-2.0)
        - `sourceDurationMs` integer — Original source audio duration in milliseconds (read-only)
        - `clipType` string, nullable
        - `prompt` string, nullable
        - `voiceId` string, nullable
        - `duration` integer, nullable
        - `isLoop` boolean — When true, allows extending duration beyond source by looping
        - `fileFormat` string, nullable
        - `fileSize` integer, nullable
        - `createdAt` string, date-time, required
        - `updatedAt` string, date-time, required
      - `keyframes` KeyframeResponse[]
        - `id` string, required
        - `projectId` string, nullable — Project-level ownership (primary)
        - `sceneId` string, nullable — DEPRECATED: kept for backward compatibility
        - `keyframeUrl` string, required
        - `prompt` string, nullable — Prompt used to generate this keyframe
        - `imageWidth` integer, nullable
        - `imageHeight` integer, nullable
        - `imageFormat` string, nullable
        - `imageSize` integer, nullable
        - `aspectRatio` string, nullable
        - `createdAt` string, date-time, required
        - `updatedAt` string, date-time, required
        - `assets` AssetResponse[]
          - `id` string, required
          - `projectId` string, required
          - `parentAssetId` string, nullable
          - `sceneId` string, nullable
          - `keyframeId` string, nullable
          - `name` string, required
          - `prompt` string, nullable
          - `mediaType` 'image' | 'video' | 'audio'
          - `imageUrl` string, nullable
          - `imageId` string, nullable
          - `videoUrl` string, nullable
          - `audioUrl` string, nullable
          - `durationMs` integer, nullable
          - `primaryVideoId` string, nullable
          - `primaryAudioClipId` string, nullable
          - `primaryImageId` string, nullable
          - `secondaryImageIds` object, nullable
          - `hasMultipleAngles` boolean
          - `secondaryAngles` object, nullable
          - `versions` AssetVersionResponse[]
            - `id` string, required
            - `versionNumber` integer, required
            - `parentVersionId` string, nullable
            - `createdAt` string, date-time, nullable
            - `isActive` boolean
            - `thumbnailUrl` string, nullable
            - `imageUrl` string, nullable
            - `name` string, nullable
            - `prompt` string, nullable
          - `activeVersionNumber` integer
          - `createdAt` string, date-time, required
          - `updatedAt` string, date-time, required
          - `subAssets` AssetResponse[]
        - `activeVersionNumber` integer
        - `versions` KeyframeVersionResponse[]
          - `id` string, required
          - `versionNumber` integer, required
          - `parentVersionId` string, nullable
          - `createdAt` string, date-time, nullable
          - `isActive` boolean
          - `thumbnailUrl` string, nullable
          - `keyframeUrl` string, nullable
          - `prompt` string, nullable
          - `imageWidth` integer, nullable
          - `imageHeight` integer, nullable
          - `imageFormat` string, nullable
          - `imageSize` integer, nullable
          - `aspectRatio` string, nullable
          - `assetIds` string[]
        - `imageId` string, nullable
        - `modelId` string, nullable
        - `sourceImageIds` string[], nullable
        - `isUserUploaded` boolean, nullable
      - `videos` VideoResponse[]
        - `id` string, required
        - `projectId` string, nullable
        - `sceneId` string, nullable
        - `orderIndex` integer
        - `name` string, nullable — Optional name for the video
        - `description` string, nullable — Visual description of the video
        - `status` string — Generation status: pending, generating, completed, failed, dismissed
        - `errorMessage` string, nullable — Persisted generation failure reason
        - `voiceover` string, nullable — Voiceover text for this video
        - `volume` integer — Volume level 0-200 (percentage)
        - `sourceCode` string, nullable — Source code snapshot for generated/editable videos
        - `workspaceArchiveUrl` string, nullable — Durable workspace archive URL for generated/editable videos
        - `workspaceArchiveSha256` string, nullable
        - `workspaceArchiveSizeBytes` integer, nullable
        - `workspaceArchiveCreatedAt` string, date-time, nullable
        - `videoUrl` string, nullable
        - `baseVideoUrl` string, nullable
        - `captionStyles` object, nullable
        - `hlsUrl` string, nullable
        - `model` string, required
        - `prompt` string, nullable
        - `duration` integer, required
        - `playbackSpeed` number
        - `cropStartMs` integer — Milliseconds trimmed from start (soft crop)
        - `cropEndMs` integer — Milliseconds trimmed from end (soft crop)
        - `startKeyframeId` string, nullable
        - `endKeyframeId` string, nullable
        - `lipSyncAudioClipId` string, nullable
        - `elements` object — Per-video element references (e.g., {startKeyframeID,prompt[,endKeyframeID]})
        - `audioClips` AudioClipResponse[]
          - `id` string, required
          - `sceneId` string, nullable
          - `videoId` string, nullable
          - `name` string, nullable
          - `audioUrl` string, required
          - `startTimestamp` integer, required
          - `trimStartMs` integer — Milliseconds trimmed from start of the source audio (in-point offset)
          - `volume` integer — Volume level 0-200 (percentage)
          - `speed` number — Playback speed multiplier (0.5-2.0)
          - `sourceDurationMs` integer — Original source audio duration in milliseconds (read-only)
          - `clipType` string, nullable
          - `prompt` string, nullable
          - `voiceId` string, nullable
          - `duration` integer, nullable
          - `isLoop` boolean — When true, allows extending duration beyond source by looping
          - `fileFormat` string, nullable
          - `fileSize` integer, nullable
          - `createdAt` string, date-time, required
          - `updatedAt` string, date-time, required
        - `modelId` string, nullable — FK to models(id)
        - `prompts` object[], nullable — [{prompt_str, duration}, ...]
        - `imageRefs` object[], nullable — [{image_id, type}, ...]
        - `videoRefs` object[], nullable — Source video refs (v2v, motion-control, remix); each entry is {id, role}
        - `assetRefs` string[], nullable — Ids of asset overlays / elements
        - `generationParams` object, nullable — Model-specific knobs
        - `createdAt` string, date-time, required
        - `updatedAt` string, date-time, required
        - `activeVersionNumber` integer
        - `versions` VideoVersionResponse[]
          - `id` string, required
          - `versionNumber` integer, required
          - `parentVersionId` string, nullable
          - `createdAt` string, date-time, nullable
          - `isActive` boolean
          - `previewUrl` string, nullable
          - `videoUrl` string, nullable
          - `hlsUrl` string, nullable
          - `prompt` string, nullable
          - `model` string, nullable
          - `duration` integer, nullable
          - `status` string, nullable
          - `errorMessage` string, nullable
          - `description` string, nullable
          - `voiceover` string, nullable
          - `volume` integer, nullable
          - `sourceCode` string, nullable
          - `workspaceArchiveUrl` string, nullable
          - `workspaceArchiveSha256` string, nullable
          - `workspaceArchiveSizeBytes` integer, nullable
          - `workspaceArchiveCreatedAt` string, date-time, nullable
          - `playbackSpeed` number
          - `cropStartMs` integer
          - `cropEndMs` integer
          - `orderIndex` integer
          - `startKeyframeId` string, nullable
          - `endKeyframeId` string, nullable
          - `lipSyncAudioClipId` string, nullable
          - `elements` object
          - `associatedKeyframes` object[]
      - `assets` AssetResponse[]
        - `id` string, required
        - `projectId` string, required
        - `parentAssetId` string, nullable
        - `sceneId` string, nullable
        - `keyframeId` string, nullable
        - `name` string, required
        - `prompt` string, nullable
        - `mediaType` 'image' | 'video' | 'audio'
        - `imageUrl` string, nullable
        - `imageId` string, nullable
        - `videoUrl` string, nullable
        - `audioUrl` string, nullable
        - `durationMs` integer, nullable
        - `primaryVideoId` string, nullable
        - `primaryAudioClipId` string, nullable
        - `primaryImageId` string, nullable
        - `secondaryImageIds` object, nullable
        - `hasMultipleAngles` boolean
        - `secondaryAngles` object, nullable
        - `versions` AssetVersionResponse[]
          - `id` string, required
          - `versionNumber` integer, required
          - `parentVersionId` string, nullable
          - `createdAt` string, date-time, nullable
          - `isActive` boolean
          - `thumbnailUrl` string, nullable
          - `imageUrl` string, nullable
          - `name` string, nullable
          - `prompt` string, nullable
        - `activeVersionNumber` integer
        - `createdAt` string, date-time, required
        - `updatedAt` string, date-time, required
        - `subAssets` AssetResponse[]
      - `createdAt` string, date-time, required
      - `updatedAt` string, date-time, required
      - `videoGeneratedAt` string, date-time, nullable
      - `lipSyncAudioClipId` string, nullable
    - `attachments` AttachmentResponse[]
      - `id` string, required
      - `projectId` string, required
      - `fileName` string, required
      - `fileSize` integer, required
      - `fileType` string, required
      - `storageUrl` string, required
      - `storageKey` string, required
      - `extractedText` string, nullable
      - `uploadedAt` string, date-time, required
    - `assets` AssetResponse[]
      - `id` string, required
      - `projectId` string, required
      - `parentAssetId` string, nullable
      - `sceneId` string, nullable
      - `keyframeId` string, nullable
      - `name` string, required
      - `prompt` string, nullable
      - `mediaType` 'image' | 'video' | 'audio'
      - `imageUrl` string, nullable
      - `imageId` string, nullable
      - `videoUrl` string, nullable
      - `audioUrl` string, nullable
      - `durationMs` integer, nullable
      - `primaryVideoId` string, nullable
      - `primaryAudioClipId` string, nullable
      - `primaryImageId` string, nullable
      - `secondaryImageIds` object, nullable
      - `hasMultipleAngles` boolean
      - `secondaryAngles` object, nullable
      - `versions` AssetVersionResponse[]
        - `id` string, required
        - `versionNumber` integer, required
        - `parentVersionId` string, nullable
        - `createdAt` string, date-time, nullable
        - `isActive` boolean
        - `thumbnailUrl` string, nullable
        - `imageUrl` string, nullable
        - `name` string, nullable
        - `prompt` string, nullable
      - `activeVersionNumber` integer
      - `createdAt` string, date-time, required
      - `updatedAt` string, date-time, required
      - `subAssets` AssetResponse[]
    - `voices` VoiceResponse[]
      - `id` string, required
      - `projectId` string, nullable
      - `userId` string, nullable
      - `name` string, required
      - `description` string, required
      - `generationId` string, nullable
      - `provider` string, nullable — Voice provider (e.g., hume, elevenlabs, seed-audio)
      - `klingVoiceId` string, nullable
      - `previewUrl` string, nullable
      - `languages` string[], nullable
      - `status` string, required
      - `createdAt` string, date-time, required
      - `updatedAt` string, date-time, required
    - `sceneCount` integer, required
    - `totalDuration` integer, nullable
    - `createdAt` string, date-time, required
    - `updatedAt` string, date-time, required
    - `completedAt` string, date-time, nullable
    - `renderedVideoUrl` string, nullable
    - `format` string
    - `workspaceVersion` integer, nullable

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.dev/latted/apis/motion-graphics-designer-api.md) · [All operations](https://skmtc.dev/latted/apis/motion-graphics-designer-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/latted/motion-graphics-designer-api/revisions/36d149b525df/schema)
