Skip to main content

Locations

Locations belong to a project and can be assigned to scenes. Each location can have an AI-generated or manually uploaded background image. The AI endpoints help writers discover consistent settings.

Endpoints overview

MethodEndpointPermissionDescription
GET/api/locations/project/:projectIdauthenticatedList locations by project
GET/api/locations/:idauthenticatedGet location by ID
POST/api/locationslocation:createCreate a location
PUT / PATCH/api/locations/:idlocation:editUpdate a location
DELETE/api/locations/:idlocation:deleteDelete a location
POST/api/locations/:id/generate-imagelocation:image:generateGenerate location image (AI)
POST/api/locations/:id/upload-imagelocation:image:uploadUpload location image (base64)
POST/api/locations/ai/recommendauthenticatedAI location recommendation
POST/api/locations/ai/check-duplicateauthenticatedAI duplicate check

Endpoints

List locations by project

GET /api/locations/project/:projectId — Auth required

Response200

{
"locations": [
{
"id": "loc-uuid-001",
"projectId": "proj-uuid-001",
"name": "Underground Lab",
"nameI18n": { "uk": "Підземна лабораторія", "en": "Underground Lab", "es": "Laboratorio subterráneo" },
"description": "A dimly lit research facility carved into the bedrock.",
"descriptionI18n": { "uk": "Слабо освітлена дослідницька установа.", "en": "A dimly lit research facility carved into the bedrock.", "es": "Una instalación de investigación tenuemente iluminada." },
"imageUrl": "/api/locations/file/proj-uuid/loc-uuid/background.png",
"generationParams": {
"prompt": "Underground lab, dim lighting, sci-fi",
"width": 1920,
"height": 1088,
"steps": 28,
"guidanceScale": 3.5,
"noiseLevel": 0.35,
"seed": null
},
"createdAt": "2025-02-01T10:00:00.000Z",
"updatedAt": "2025-03-01T10:00:00.000Z"
}
],
"total": 1
}

Get location by ID

GET /api/locations/:id — Auth required

Response200 — single location object (same shape as list item)


Create location

POST /api/locations — Auth required, Permission: location:create

Request body

{
"projectId": "proj-uuid-001",
"name": "Underground Lab",
"description": "A dimly lit research facility carved into the bedrock."
}
FieldRequiredNotes
projectIdyesUUID of the parent project
nameyesAuto-translated to all locales
descriptionnoAuto-translated if provided

Response201 — created location object


Update location

PUT /api/locations/:id or PATCH /api/locations/:id — Auth required, Permission: location:edit

Request body (all fields optional)

{
"name": "Deep Underground Lab",
"description": "An even more secret facility."
}

Response200 — updated location object


Delete location

DELETE /api/locations/:id — Auth required, Permission: location:delete

Response204


Generate location image (AI)

POST /api/locations/:id/generate-image — Auth required, Rate limited, Permission: location:image:generate

Request body

{
"prompt": "Underground lab, dim lighting, stone walls, sci-fi equipment",
"model": "flux",
"width": 1920,
"height": 1088,
"steps": 28,
"guidanceScale": 3.5,
"noiseLevel": 0.35,
"seed": null
}
FieldRequiredDefault
promptyes
modelno"flux"
widthno1920
heightno1088
stepsno28
guidanceScaleno3.5
noiseLevelno0.35
seednonull

Response200 — updated location object with imageUrl and generationParams


Upload location image (base64)

POST /api/locations/:id/upload-image — Auth required, Permission: location:image:upload

Request body

{
"imageBase64": "<base64-encoded-image-data>",
"mimeType": "image/png"
}

imageBase64 may include the data:image/png;base64, prefix — it will be stripped automatically.

Response200 — updated location object with imageUrl set


AI location recommendation

POST /api/locations/ai/recommend — Auth required, Rate limited

Given a scene's blocks and the project's existing locations, recommends the best matching or new locations.

Request body

{
"sceneBlocks": [
{ "type": "action", "text": "The hero enters a dark tunnel" },
{ "type": "dialog", "text": "It's so cold in here…" }
],
"existingLocations": [
{ "id": "loc-uuid-001", "name": "Underground Lab", "description": "Dimly lit facility" }
]
}

Response200

{
"recommendation": "Underground Lab",
"confidence": "high",
"reasoning": "The scene takes place in a cold, dark space — matches the underground lab description."
}

AI duplicate check

POST /api/locations/ai/check-duplicate — Auth required, Rate limited

Checks whether a proposed new location is semantically too similar to an existing one.

Request body

{
"name": "Dark Lab",
"description": "Underground research station with stone walls.",
"existingLocations": [
{ "id": "loc-uuid-001", "name": "Underground Lab", "description": "A dimly lit research facility carved into the bedrock." }
]
}

Response200

{
"isDuplicate": true,
"matchedLocation": { "id": "loc-uuid-001", "name": "Underground Lab" },
"confidence": "high",
"reasoning": "Both describe a dark underground research facility — effectively the same location."
}