Public API
Zeabur’s API is primarily built using GraphQL and serves as the foundation for a series of Zeabur products such as Zeabur Dashboard and Zeabur CLI. We provide a public API that allows you to control Zeabur through code. Additionally, Zeabur has placed some JSON schemas and OpenAPI specifications for non-GraphQL APIs in the Schema Repository.
Authentication
You need to provide your API key in the Authorization
header to use the Zeabur API with your identity. For instructions on generating an API key, please read this document.
Here’s an example of how to include it:
curl --request POST \
--url https://api.zeabur.com/graphql \
--header 'Authorization: Bearer {YOUR_API_TOKEN}' \
--header 'Content-Type: application/json' \
--data '{"query":"query { me { username } }"}'
GraphQL API
You can visit our Apollo Explorer to view all available Zeabur API GraphQL methods, test them, and copy them as cURL commands.
If you prefer writing GraphQL in an IDE or need type hints, you can download the complete Zeabur API Schema from the Explorer under “Schema” → “SDL”.
If you find that the API you need is not in this Schema, please let us know through our Discord.
Local Project Upload API
While deploying from a Git Repository is the mainstream method, there are times when you need to directly deploy a pre-packaged application. Common scenarios include:
- Your CI/CD process produces a built artifact, such as a .zip file.
- You want to manually upload a project but do not want to associate it with a Git Repository.
The Zeabur Upload API provides an API that allows you to directly upload a ZIP file, which Zeabur will automatically extract and deploy to your project.
Core Concept: Secure Upload Using Pre-signed URL
The Zeabur Upload API issues you a Pre-signed URL, which is a temporary, secure link granting you one-time permission to directly upload files to Zeabur’s code staging area.
The entire workflow can be represented by the following sequence diagram:
Upload Process
Before starting the upload, you need to obtain two pieces of information about the file:
content_length
: The size of the file in bytes.content_hash
: The SHA256 hash of the file content, encoded in Base64.
Then you can create an upload stage. First, you need to inform Zeabur that you are ready to upload a file.
POST /v2/upload
Content-Type: application/json
{
"content_hash": "Your calculated BASE64 encoded SHA256 hash",
"content_hash_algorithm": "sha256",
"content_length": 12345678
}
If successful (201 Created), Zeabur will return details of the Pre-signed URL and an upload_id
to track this upload stage.
{
"presign_header": { "Content-Type": "application/zip" },
"presign_method": "PUT",
"presign_url": "https://zeabur-uploads.s3.ap-east-1.amazonaws.com/...",
"upload_id": "A unique UPLOAD_ID"
}
Next, use the information obtained in the previous step to upload your file. Note that this request is sent to the presign_url
, not the Zeabur API.
- Method: PUT (or the method returned by presign_method in the previous step)
- URL: The
presign_url
from the previous response. - Headers: You must include the headers returned in
presign_header
(e.g., Content-Type: application/zip). - Body: The raw binary data of your zip file.
When this request receives a 200 OK response, it means your file has been securely stored. Finally, you need to inform Zeabur that the file is ready and how to process it. Use the upload_id
obtained earlier to call the POST /v2/upload/{upload_id}/prepare
endpoint.
POST /v2/upload/{upload_id}/prepare
Content-Type: application/json
Authorization: Bearer {YOUR_API_TOKEN}
Depending on your goal, there are two options for the Request Body. If you want to upload to an existing project, you need to provide service_id
and environment_id
. This type will return a url
pointing to the ongoing deployment, which you can redirect users to so they can view the deployment status.
{
"upload_type": "existing_service",
"service_id": "The ID of your existing service",
"environment_id": "The ID of your service environment"
}
If you want to guide users to create a project, you only need to pass in new_project
as the upload_type
. This type will return a url
that can guide users to create a project, which you can redirect them to.
{
"upload_type": "new_project"
}
Documentation and Schema
For complete documentation and the OpenAPI schema, refer to the Upload API Documentation.
Template Deployment API
If you have a template specification YAML file, you can use this GraphQL mutation to deploy it to a specified project:
mutation DeployTemplate($rawSpecYaml: String, $projectId: ObjectID) {
deployTemplate(rawSpecYaml: $rawSpecYaml, projectID: $projectId) {
_id # String!
}
}
This API is suitable for bulk deployments.
Container Operation API
These APIs allow you to upload files to or download files from a specified Zeabur service, and also send commands to a specified Zeabur service.
Upload File
Currently, there is a 100MB file size limit for uploads.
POST https://api.zeabur.com/projects/project-id/services/service-id/files
Content-Type: multipart/form-data
Authorization: Bearer <YOUR_API_TOKEN>
- Payload (Form Content)
- file (Blob): File content
- path (string): File path
- environment (string): The environment ID, which can be obtained from the
envID
in the Dashboard URL
- Response
- 200 OK
- 500 Internal Server Error, such as
{"code": "INTERNAL_SERVER_ERROR", "error": "failed to upload file"}
Download File
GET https://api.zeabur.com/projects/project-id/services/service-id/files?path=[PATH]&environment=[ENVIRONMENT]
Authorization: Bearer <YOUR_API_TOKEN>
- Query
- path (string): File path
- environment (string): The environment ID, which can be obtained from the
envID
in the Dashboard URL
- Response
- 200 OK,
application/octet-stream
- 500 Internal Server Error, such as
{"code": "INTERNAL_SERVER_ERROR", "error": "failed to download file"}
- 200 OK,
List Files
Use the “Execute Single Command” API to run:
$ ls -A -a -F -1 /
Delete Files
Use the “Execute Single Command” API to run:
$ rm -r FILENAME
Execute Single Command
Use the GraphQL API to execute:
mutation ExecuteCommand($serviceId: ObjectID!, $environmentId: ObjectID!, $command: [String!]!) {
executeCommand(serviceID: $serviceId, environmentID: $environmentId, command: $command) {
exitCode # Int!
output # String!
}
}
Use WebSocket to Access Service Terminal
- WebSocket endpoint:
wss://api.zeabur.com/exec/<service-id>
- Writing content to the WebSocket is the actual input
- Resize Control Controls:
[RESIZE_CONTROL, COLS_LSB, COLS_MSB, ROWS_LSB, ROWS_MSB]
const buffer = new Uint8Array([ RESIZE_CONTROL, dims.cols & 0xFF, dims.cols >> 8, dims.rows & 0xFF, dims.rows >> 8 ]);
Retrieve Build Logs
Use the GraphQL API to execute:
query BuildLogs($projectId: ObjectID!, $deploymentId: ObjectID!, $timestampCursor: Time) {
buildLogs(projectID: $projectId, deploymentID: $deploymentId, timestampCursor: $timestampCursor) {
message # String!
timestamp # Time!
}
}
Retrieve Runtime Logs
Use the GraphQL API to execute:
query RuntimeLogs($projectId: ObjectID!, $serviceId: ObjectID!, $environmentId: ObjectID!, $timestampCursor: Time) {
runtimeLogs(projectID: $projectId, serviceID: $serviceId, environmentID: $environmentId, timestampCursor: $timestampCursor) {
message # String!
timestamp # Time!
}
}
Subscribe to Build Logs
Use the GraphQL API to execute:
subscription BuildLogReceived($projectId: ObjectID!, $deploymentId: ObjectID!) {
buildLogReceived(projectID: $projectId, deploymentID: $deploymentId) {
message # String!
timestamp # Time!
}
}
Subscribe to Runtime Logs
Use the GraphQL API to execute:
subscription RuntimeLogReceived($projectId: ObjectID!, $serviceId: ObjectID!, $environmentId: ObjectID!) {
runtimeLogReceived(projectID: $projectId, serviceID: $serviceId, environmentID: $environmentId) {
message # String!
timestamp # Time!
}
}