Upload endpoints - request a signed URL, PUT the archive, complete the upload, then create an application from it.
Uploads
Deploying without a repository takes three calls and one PUT. The archive goes straight to storage over a signed URL, so it never passes through the API.
POST /api/upload/request-url— get a signed URL and anuploadIdPUTthe zip to that URLPOST /api/upload/complete— tell the platform the bytes landedPOST /api/applications/create-from-upload— build and deploy it
Tip
Zip the contents of the project directory, not the directory itself. A single top-level folder inside the archive puts every path one level deeper than the build expects.
Request an upload URL#
/api/upload/request-urlReserves an upload and returns a signed URL valid for 15 minutes. maxSize is 100 MB by default; passing a larger fileSize is rejected before you waste the transfer.
- permission
- create:projects
Parameters
fileNamestringdefault source.zip- Name recorded for the archive
contentTypestringdefault application/zip- Must match the Content-Type you PUT with
fileSizenumberoptional- Bytes. Checked against maxSize up front
targetOrganisationIdstringsession only- Required when using a session token
curl -X POST https://api.light-cloud.com/api/upload/request-url \
-H "Authorization: Bearer $LIGHT_CLOUD_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"fileSize\": $(wc -c < source.zip)}"{
"uploadId": "upl_8Xa1",
"signedUrl": "https://storage.googleapis.com/lc-uploads/...",
"gcsPath": "uploads/org_1Ab/upl_8Xa1/source.zip",
"expiresAt": "2026-08-28T07:15:00.000Z",
"maxSize": 104857600
}Upload the archive#
The PUT goes to the signed URL, not to the API. No Authorization header — the signature is the authorisation. The Content-Type must match what you asked for, or the signature will not verify.
curl -X PUT "$SIGNED_URL" \
-H "Content-Type: application/zip" \
--upload-file source.zipComplete the upload#
/api/upload/completeConfirms the bytes landed and records what the archive is. The detection fields are hints carried through to the create call — leave them out and the platform inspects the archive itself.
- permission
- create:projects
Parameters
uploadIdstringrequired- From request-url
detectedFrameworkstringoptional- What you believe this is
detectedRuntimestringoptional- Container only
detectedDeploymentTypestringoptionalstaticorcontainerdetectedBuildCommandstringoptional- Command that produces the build
detectedOutputDirectorystringoptional- Static only
targetOrganisationIdstringsession only- Required when using a session token
curl -X POST https://api.light-cloud.com/api/upload/complete \
-H "Authorization: Bearer $LIGHT_CLOUD_API_KEY" \
-H "Content-Type: application/json" \
-d '{"uploadId": "upl_8Xa1", "detectedDeploymentType": "static"}'{
"uploadId": "upl_8Xa1",
"status": "ready",
"size": 4823910
}Clean up abandoned uploads#
/api/upload/cleanupDiscards uploads that were reserved but never completed.
- permission
- create:projects
Parameters
targetOrganisationIdstringsession only- Required when using a session token
curl -X POST https://api.light-cloud.com/api/upload/cleanup \
-H "Authorization: Bearer $LIGHT_CLOUD_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'{ "removed": 3 }The whole flow#
#!/usr/bin/env bash
set -euo pipefail
API=https://api.light-cloud.com
AUTH=(-H "Authorization: Bearer $LIGHT_CLOUD_API_KEY" -H "Content-Type: application/json")
(cd dist && zip -qr ../source.zip .)
upload=$(curl -sS -X POST "$API/api/upload/request-url" "${AUTH[@]}" \
-d "{\"fileSize\":$(wc -c < source.zip)}")
UPLOAD_ID=$(echo "$upload" | jq -r .uploadId)
SIGNED_URL=$(echo "$upload" | jq -r .signedUrl)
curl -sS -X PUT "$SIGNED_URL" \
-H "Content-Type: application/zip" \
--upload-file source.zip
curl -sS -o /dev/null -X POST "$API/api/upload/complete" "${AUTH[@]}" \
-d "{\"uploadId\":\"$UPLOAD_ID\",\"detectedDeploymentType\":\"static\"}"
curl -sS -X POST "$API/api/applications/create-from-upload" "${AUTH[@]}" \
-d "{
\"name\": \"marketing-site\",
\"uploadId\": \"$UPLOAD_ID\",
\"deploymentType\": \"static\",
\"outputDirectory\": \".\"
}"