Skip to main content

Media Management

Photos, video, floor plans and the rest of a shoot's output attach to a project. Uploads do not pass through the Vremly API — the API issues a presigned S3 URL, your client sends the bytes straight to S3, and then you tell Vremly the object exists.

Media types

mediaType accepts exactly these values:

ValueWhat it is
PHOTOStill photography — HDR, twilight, aerial
VIDEOWalkthroughs and cinematic tours
FLOORPLAN2D and 3D floor plans
VIRTUAL_TOURPanoramic tour assets
PROPERTY_WEBSITEProperty site assets
BROCHUREGenerated print material
DOCUMENTSupporting files

Uploading

Three steps. There is no single-request upload endpoint — a multipart POST of a 60MB RAW file through the API would tie up a request the whole time it transferred, so the bytes go to S3 directly instead.

1. Ask for a presigned URL

curl -X POST https://api.vremly.com/media/presign \
-H "x-api-key: <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"projectId": "proj_abc123",
"filename": "front-exterior.jpg",
"contentType": "image/jpeg",
"mediaType": "PHOTO"
}'

All four fields are required. The response:

{
"uploadUrl": "https://s3.amazonaws.com/...&X-Amz-Signature=...",
"key": "org_.../proj_abc123/photo/front-exterior.jpg",
"cdnUrl": "https://cdn.example.com/org_.../proj_abc123/photo/front-exterior.jpg"
}
The presigned URL is the upload authority

Anyone holding that URL can write that object for the hour it stays valid, no credential required. Vremly checks your permission at the moment it issues the URL, not when the bytes arrive. Treat it like a password: do not log it, and do not hand it to a browser you do not control.

2. PUT the bytes to S3

Send the file to uploadUrl directly. No Vremly headers — not x-api-key, not Authorization. The signature covers the request, and adding headers it was not signed with makes S3 reject it.

curl -X PUT "<uploadUrl>" \
-H "Content-Type: image/jpeg" \
--data-binary @front-exterior.jpg

The Content-Type must match the contentType you presigned with, for the same reason.

3. Confirm it

S3 does not tell Vremly about the object, so this step is what creates the media record. Skip it and the file sits in the bucket, invisible in the app.

curl -X POST https://api.vremly.com/media/confirm-upload \
-H "x-api-key: <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"projectId": "proj_abc123",
"filename": "front-exterior.jpg",
"size": 4194304,
"type": "PHOTO",
"key": "org_.../proj_abc123/photo/front-exterior.jpg",
"cdnUrl": "https://cdn.example.com/..."
}'

projectId, filename, size and type are required. Pass back the key and cdnUrl you were given in step 1.

Listing a project's media

curl https://api.vremly.com/media/project/proj_abc123 \
-H "x-api-key: <your-api-key>"

The project's own route returns the same set:

curl https://api.vremly.com/projects/proj_abc123/media \
-H "x-api-key: <your-api-key>"

Other operations

MethodPathPurpose
PATCH/media/reorderChange display order
PATCH/media/{id}/renameRename a file
DELETE/media/{id}Remove an item
GET/media/{id}Fetch one item

Uploading, changing or deleting media needs a key with WRITE; listing needs only READ. See Authentication.

Delivery is separate

Getting media onto a project is not the same as delivering it to the client. Delivery has its own routes and its own events — PROJECT_DELIVERED when your team sends the work, DELIVERY_APPROVED when the client accepts it. See Webhooks.