DeveloperPublic API

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"}

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!
  }
}