Code API
The Code API provides endpoints to handle code uploads so you can trigger new builds and deployments via API to your app's environments.
We do this process through pre-signed URLs. This is a three-step process:
- Request a pre-signed URL
- Zip and Upload your code to the pre-signed URL
- Notify Quave ONE about the upload
Ignoring unnecessary files
It's important to avoid sending files that will be generated at build time, like .git, node_modules, .meteor/local, etc as they are usually large and not needed to build your app, if you do so you will probably wait a long time for the upload to complete or even reach a limit.
Our CLI does this respecting .zcloudignore files but as you are sending the file you need to do it yourself.
For a bash equivalent, you could use rsync with exclude patterns:
rsync -av --exclude='node_modules' \
--exclude='.git' \
--exclude='.meteor/local' \
source/ destination/
Then instead of zipping the source directory you should zip the destination directory.
Ok, let's learn the steps to upload your code.
1. Request Storage Key
First, request a pre-signed URL, with a storage key by sending a POST request to the /api/public/v1/app-env/request-storage-key endpoint.
| Body Parameter | Type | Description |
|---|---|---|
envName | String | The environment name (required) |
fileExtension | String | The extension of the file to upload (optional). Allowed values are .zip, .tgz, .tar.gz. Defaults to .tgz. |
Example request:
curl -X POST \
-H 'Authorization: YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"envName": "my-environment"}' \
https://api.quave.cloud/api/public/v1/app-env/request-storage-key
Example Response:
{
"uploadUrl": "https://storage.aws.com/bucket-name/...",
"storageKey": "s3://bucket-name/environment/account-id/app-id/random-id-my-environment.zip",
"envUrl": "https://app.quave.cloud/account/account-id/app/app-id/env/env-id"
}
2. Zip and Upload Your Code
After receiving the pre-signed URL, zip and upload your code to the pre-signed URL.
To zip your code, you can use the following command:
tar -czvf ../project.tgz --exclude="node_modules" --exclude=".git" --exclude="*.zip" --exclude="*.env" *
Example using curl:
curl -X PUT \
-H 'Content-Type: application/x-gzip' \
--data-binary '@/path/to/your/file.tgz' \
"PRESIGNED_URL_FROM_PREVIOUS_STEP"
Important notes:
- The pre-signed URL expires after 60 minutes
- Make sure to set the correct Content-Type header
- Use the exact URL returned in the
uploadUrlfield
3. Notify Upload Event
Finally, notify Quave ONE that the upload is complete by sending a POST request to the /api/public/v1/app-env/upload-storage-event endpoint.
| Body Parameter | Type | Description |
|---|---|---|
envName | String | The environment name (required) |
storageKey | String | The storage key received from the request-key endpoint |
startupConfig | Object | Optional partial persistent startup configuration with command, args, shell, or workingDir. |
clearStartupConfig | Boolean | Set to true to clear the complete saved startup override. Cannot be combined with startupConfig. |
replaceStartupConfig | Boolean | Set to true with startupConfig to replace the complete saved override instead of merging omitted fields. |
Example request:
curl -X POST \
-H 'Authorization: YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"envName": "my-environment",
"storageKey": "s3://bucket-name/path/to/file.zip",
"startupConfig": {
"command": "bun run start:worker",
"shell": true
},
"replaceStartupConfig": true
}' \
https://api.quave.cloud/api/public/v1/app-env/upload-storage-event
Example Response:
{
"status": "Ok",
"uploadEventId": "upload-event-id"
}
The uploadEventId identifies the asynchronous source-upload event. You can use
it to correlate this upload with latestDeployment.uploadEventId from the
App Environment Status API while a source build is still
BUILDING and before it becomes the current deployment.
Complete Flow Example
Here's a complete example using bash:
# Set your variables
ENV_NAME="my-environment"
API_TOKEN="YOUR_TOKEN"
FILE_PATH="/path/to/your/file.tgz"
API_URL="https://api.quave.cloud/api/public/v1"
# Step 1: Request pre-signed URL
RESPONSE=$(curl -X POST \
-H "Authorization: ${API_TOKEN}" \
-H 'Content-Type: application/json' \
-d "{\"envName\": \"${ENV_NAME}\"}" \
"${API_URL}/app-env/request-storage-key")
# Extract values from response
UPLOAD_URL=$(echo $RESPONSE | jq -r '.uploadUrl')
STORAGE_KEY=$(echo $RESPONSE | jq -r '.storageKey')
# Step 2: Upload file to storage
curl -X PUT \
-H 'Content-Type: application/x-gzip' \
--data-binary "@${FILE_PATH}" \
"$UPLOAD_URL"
# Step 3: Notify upload event
UPLOAD_EVENT_RESPONSE=$(curl -X POST \
-H "Authorization: ${API_TOKEN}" \
-H 'Content-Type: application/json' \
-d "{
\"envName\": \"${ENV_NAME}\",
\"storageKey\": \"${STORAGE_KEY}\",
\"startupConfig\": {
\"command\": \"bun run start:worker\",
\"shell\": true
},
\"replaceStartupConfig\": true
}" \
"${API_URL}/app-env/upload-storage-event")
UPLOAD_EVENT_ID=$(echo $UPLOAD_EVENT_RESPONSE | jq -r '.uploadEventId')
Error Handling
Common errors and their solutions:
| Error | Solution |
|---|---|
| Pre-signed URL expired | Request a new pre-signed URL |
| Invalid content type | Ensure you're sending the correct Content-Type header |
| Environment not found | Verify the environment name is correct |
| Invalid storage key | Use the exact storage key from the request-storage-key response |
Important Notes
- The Code API is designed for uploading application code and related files, it's designed to be used with our CLI option as deployment configuration;
- For apps using GitHub connected repositories, use the GitHub integration instead by pushing new commits to the configured branch;
- Always complete all three steps in the process;
- The upload-event response includes
uploadEventIdfor correlating status polling with the exact source upload; - The optional startup configuration is saved on the app environment before the build. It affects runtime only and is not included in the build hash;
- Startup configuration patches preserve omitted saved fields. Send
replaceStartupConfig: truewithstartupConfigwhen the object is the complete desired override and omitted fields must be removed. UseclearStartupConfig: trueto restore all image defaults; - Startup configuration is supported for regular Apps and Functions, but not for Jobs or Databases & Services. See Startup Command Overrides;
- Keep your pre-signed URLs secure and don't share them;
- The upload must be completed within the pre-signed URL expiration time;