curl --request GET \
--url https://api.example.com/api/projects/:id{
"project": {
"project.id": "<string>",
"project.workspaceId": "<string>",
"project.userId": "<string>",
"project.name": "<string>",
"project.styleTemplateId": "<string>",
"project.roomType": {},
"project.thumbnailUrl": {},
"project.status": "<string>",
"project.imageCount": 123,
"project.completedCount": 123,
"project.createdAt": "<string>",
"project.updatedAt": "<string>"
},
"images": [
{
"images[].id": "<string>",
"images[].workspaceId": "<string>",
"images[].userId": "<string>",
"images[].projectId": "<string>",
"images[].originalImageUrl": "<string>",
"images[].resultImageUrl": {},
"images[].prompt": "<string>",
"images[].version": 123,
"images[].parentId": {},
"images[].status": "<string>",
"images[].errorMessage": {},
"images[].metadata": {},
"images[].createdAt": "<string>",
"images[].updatedAt": "<string>"
}
]
}Retrieve a single project with all associated images and generation history
curl --request GET \
--url https://api.example.com/api/projects/:id{
"project": {
"project.id": "<string>",
"project.workspaceId": "<string>",
"project.userId": "<string>",
"project.name": "<string>",
"project.styleTemplateId": "<string>",
"project.roomType": {},
"project.thumbnailUrl": {},
"project.status": "<string>",
"project.imageCount": 123,
"project.completedCount": 123,
"project.createdAt": "<string>",
"project.updatedAt": "<string>"
},
"images": [
{
"images[].id": "<string>",
"images[].workspaceId": "<string>",
"images[].userId": "<string>",
"images[].projectId": "<string>",
"images[].originalImageUrl": "<string>",
"images[].resultImageUrl": {},
"images[].prompt": "<string>",
"images[].version": 123,
"images[].parentId": {},
"images[].status": "<string>",
"images[].errorMessage": {},
"images[].metadata": {},
"images[].createdAt": "<string>",
"images[].updatedAt": "<string>"
}
]
}a1b2c3d4-5678-90ab-cdef-1234567890abGET /api/projects/a1b2c3d4-5678-90ab-cdef-1234567890ab
living-room, bedroom, kitchen).pending, processing, completed, or failed.null if still processing or failed.1 for original, increments for each edit.null for root images (version 1).pending - Queued for processingprocessing - Currently being processed by AIcompleted - Successfully processedfailed - Processing failedfailed.{
"project": {
"id": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
"workspaceId": "ws_abc123",
"userId": "user_xyz789",
"name": "Sunset Villa - Master Bedroom",
"styleTemplateId": "modern-scandinavian",
"roomType": "bedroom",
"thumbnailUrl": "https://storage.example.com/thumbnails/abc123.jpg",
"status": "completed",
"imageCount": 3,
"completedCount": 3,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T11:45:00.000Z"
},
"images": [
{
"id": "img_001",
"workspaceId": "ws_abc123",
"userId": "user_xyz789",
"projectId": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
"originalImageUrl": "https://storage.example.com/originals/photo1.jpg",
"resultImageUrl": "https://storage.example.com/results/photo1_edited.jpg",
"prompt": "Modern Scandinavian bedroom with warm natural light, minimalist furniture, and neutral tones",
"version": 1,
"parentId": null,
"status": "completed",
"errorMessage": null,
"metadata": {
"model": "flux-pro/v1.1",
"processingTime": 12.5,
"cost": 0.05
},
"createdAt": "2024-01-15T10:35:00.000Z",
"updatedAt": "2024-01-15T10:35:15.000Z"
},
{
"id": "img_002",
"workspaceId": "ws_abc123",
"userId": "user_xyz789",
"projectId": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
"originalImageUrl": "https://storage.example.com/results/photo1_edited.jpg",
"resultImageUrl": "https://storage.example.com/results/photo1_edited_v2.jpg",
"prompt": "Modern Scandinavian bedroom with warmer lighting and added decorative pillows",
"version": 2,
"parentId": "img_001",
"status": "completed",
"errorMessage": null,
"metadata": {
"model": "flux-pro/v1.1",
"processingTime": 11.8,
"cost": 0.05
},
"createdAt": "2024-01-15T11:20:00.000Z",
"updatedAt": "2024-01-15T11:20:12.000Z"
}
]
}
null
null.
project.workspaceId matches user’s workspacenull if workspace mismatch or project not foundparentId = nullparentId pointing to the rootparentId, creating a version chain:
Root Image (v1, parentId=null)
├─ Edit v2 (parentId → Root)
├─ Edit v3 (parentId → Root)
└─ Edit v4 (parentId → Root)
-- Get project
SELECT * FROM project WHERE id = $projectId LIMIT 1;
-- Get all images for project (ordered newest first)
SELECT * FROM image_generation
WHERE project_id = $projectId
ORDER BY created_at DESC;
completedCount and status are automatically updated:
completedupdateProjectCounts(projectId) to recalculategetProjectPaymentStatus(projectId)/lib/actions/payments.ts.
POST /api/process-imageGET /api/download/:projectId/app/dashboard/[id]/page.tsx:ProjectDetailPage (lines 15-85)/lib/db/queries.ts:getProjectById (lines 307-331)/lib/db/schema.ts (project: lines 164-196, imageGeneration: lines 202-241)