開發者開放 API

開放 API

Zeabur 的 API 主要使用 GraphQL 建置,同時提供為 Zeabur Dashboard、Zeabur CLI 等一系列 Zeabur 產品的基礎。我們提供開放 API,讓您能夠透過程式碼來控制 Zeabur。 另 Zeabur 在 Schema Repository 中有放置一部分非 GraphQL API 的 JSON schema 和 OpenAPI specification。

認證

您需要在 Authorization 中傳入 API 金鑰,才能使用您的身分使用 Zeabur API。產生 API 金鑰的說明,請閱讀 這篇文件

傳入範例如下:

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

您可以造訪我們的 Apollo Explorer 檢視所有可以使用的 Zeabur API GraphQL 方法、進行測試並且複製成 cURL 指令。

如果您習慣在 IDE 上編寫 GraphQL,或者需要取得類型提示,可以到 Explorer 中的「Schema」→「SDL」來下載 Zeabur API 的完整 Schema。

若您發現您需要的 API 不在這個 Schema 中,請到我們的 Discord 和我們告知。

本機專案上傳 API

雖然從 Git Repository 部署是主流方式,但有時您會需要直接部署一個預先打包好的應用程式。常見的情境包含:

  • 您的 CI/CD 流程會產出一個建置好的成品 (artifact),例如一個 .zip 檔。
  • 您想手動上傳一個專案,但不想將其與 Git Repository 連結。

Zeabur Upload API 因此提供了一個 API,讓您可以直接上傳 ZIP,而 Zeabur 會自動將 ZIP 解壓縮並且部署到您的專案中。

核心概念:使用預簽章 URL (Pre-signed URL) 進行安全上傳

Zeabur Upload API 會簽發給您一個預簽章 URL (Pre-signed URL),這個 URL 是一個暫時性、安全的連結,它授予您一次性的權限,讓您可以將檔案直接上傳到 Zeabur 的程式碼暫存空間。

整個工作流程可以用以下序列圖來表示:

上傳流程

在開始上傳之前,您需要取得關於檔案的兩項資訊:

  • content_length:檔案的大小,單位為位元組 (bytes)。
  • content_hash:檔案內容的 SHA256 雜湊值,並進行 Base64 編碼。

接著就可以建立上傳階段了。首先,您需要告知 Zeabur 您準備要上傳一個檔案。

POST /v2/upload
Content-Type: application/json
 
{
  "content_hash": "您計算出的 BASE64 編碼 SHA256 雜湊值",
  "content_hash_algorithm": "sha256",
  "content_length": 12345678
}

如果成功 (201 Created),Zeabur 會回傳預簽章 URL 的詳細資訊,以及一個用於追蹤此上傳階段的 upload_id

{
    "presign_header": { "Content-Type": "application/zip" },
    "presign_method": "PUT",
    "presign_url": "https://zeabur-uploads.s3.ap-east-1.amazonaws.com/...",
    "upload_id": "一個獨一無二的 UPLOAD_ID"
}

接著,使用上一步取得的資訊來上傳您的檔案。請注意,這個請求是發送到 presign_url,而不是 Zeabur API。

  • Method: PUT (或上一步 presign_method 回傳的方法)
  • URL: 上一步回應中的 presign_url。
  • Headers: 您必須包含 presign_header 中回傳的標頭 (例如 Content-Type: application/zip)。
  • Body: 您 zip 檔案的原始二進位資料。

當這個請求獲得 200 OK 的回應時,代表您的檔案已經安全地儲存完畢。最後,您需要告訴 Zeabur 檔案已經就緒,以及要如何處理它。使用稍早取得的 upload_id 呼叫 POST /v2/upload/{upload_id}/prepare 端點。

POST /v2/upload/{upload_id}/prepare
Content-Type: application/json
Authorization: Bearer {YOUR_API_TOKEN}

根據您的目標,Request Body 有兩種選擇。如果您要上傳到一個現有的專案中,您需要提供 service_idenvironment_id。這個 type 會回傳一個指向進行中部署的 url,您可以將使用者重新導向到這個 URL,讓使用者可以查看部署狀態。

{
  "upload_type": "existing_service",
  "service_id": "您現有服務的 ID",
  "environment_id": "您服務環境的 ID"
}

如果您想要引導使用者建立專案,則只需要傳入 new_projectupload_type 即可。這個 type 會回傳一個可以引導使用者建立專案的 url,您可以將使用者重新導向到這個 URL,讓使用者可以建立專案。

{
  "upload_type": "new_project"
}

文件和 schema

完整的文件和 OpenAPI schema 可以參考 Upload API 文件

模板部署 API

如果您有一個 模板規格 YAML 檔案,可以使用這個 GraphQL mutation 來部署到指定專案中:

mutation DeployTemplate($rawSpecYaml: String, $projectId: ObjectID) {
  deployTemplate(rawSpecYaml: $rawSpecYaml, projectID: $projectId) {
    _id  # String!
  }
}

這個 API 適合用來大量部署。

容器操作 API

這裡的 API 可以讓您將檔案上傳到或下載自 Zeabur 的指定服務,也可以向 Zeabur 的指定服務傳送指令。

上傳檔案

💡

目前上傳有 100MB 的檔案大小限制。

POST https://api.zeabur.com/projects/project-id/services/service-id/files
Content-Type: multipart/form-data
Authorization: Bearer <YOUR_API_TOKEN>
  • Payload(表單內容)
    • file (Blob):檔案內容
    • path (string):檔案路徑
    • environment (string):即 environment ID,能從 Dashboard 網址中的 envID 取得
  • Response
    • 200 OK
    • 500 Internal Server Error,如 {"code": "INTERNAL_SERVER_ERROR", "error": "failed to upload 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):檔案路徑
    • environment (string):即 environment ID,能從 Dashboard 網址中的 envID 取得
  • Response
    • 200 OK, application/octet-stream
    • 500 Internal Server Error,如 {"code": "INTERNAL_SERVER_ERROR", "error": "failed to download file"}

列舉檔案

請使用「執行單個指令」的 API 執行:

$ ls -A -a -F -1 /

刪除檔案

請使用「執行單個指令」的 API 執行:

$ rm -r FILENAME

執行單個指令

使用 GraphQL API 執行:

mutation ExecuteCommand($serviceId: ObjectID!, $environmentId: ObjectID!, $command: [String!]!) {
  executeCommand(serviceID: $serviceId, environmentID: $environmentId, command: $command) {
    exitCode  # Int!
    output    # String!
  }
}

使用 WebSocket 取得服務終端機

  • WebSocket endpoint: wss://api.zeabur.com/exec/<service-id>
  • 往 WebSocket 寫入內容即實際輸入
  • 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
    ]);

取回編譯期日誌

使用 GraphQL API 執行:

query BuildLogs($projectId: ObjectID!, $deploymentId: ObjectID!, $timestampCursor: Time) {
  buildLogs(projectID: $projectId, deploymentID: $deploymentId, timestampCursor: $timestampCursor) {
    message    # String!
    timestamp  # Time!
  }
}

取回執行期日誌

使用 GraphQL API 執行:

query RuntimeLogs($projectId: ObjectID!, $serviceId: ObjectID!, $environmentId: ObjectID!, $timestampCursor: Time) {
  runtimeLogs(projectID: $projectId, serviceID: $serviceId, environmentID: $environmentId, timestampCursor: $timestampCursor) {
    message    # String!
    timestamp  # Time!
  }
}

訂閱編譯期日誌

使用 GraphQL API 執行:

subscription BuildLogReceived($projectId: ObjectID!, $deploymentId: ObjectID!) {
  buildLogReceived(projectID: $projectId, deploymentID: $deploymentId) {
    message    # String!
    timestamp  # Time!
  }
}

訂閱執行期日誌

使用 GraphQL API 執行:

subscription RuntimeLogReceived($projectId: ObjectID!, $serviceId: ObjectID!, $environmentId: ObjectID!) {
  runtimeLogReceived(projectID: $projectId, serviceID: $serviceId, environmentID: $environmentId) {
    message    # String!
    timestamp  # Time!
  }
}