| name | auth |
| description | Use when setting up or verifying Zeabur API access for Toolkit skills. Use when ZEABUR_API_KEY is missing, when any Zeabur GraphQL call returns an authentication error, or when the user asks "how do I log in to Zeabur", "set up my Zeabur token", or "am I authenticated". Prefer this over the CLI-based zeabur-* skills for server operations — this one talks to the GraphQL API directly and needs no CLI. |
Zeabur Toolkit Auth
All Toolkit skills call the Zeabur GraphQL API at https://api.zeabur.com/graphql with curl. There is no CLI. Authentication is a personal Access Token passed as a Bearer token.
Getting a token
If ZEABUR_API_KEY is not set, walk the user through this — the token is created in the browser, not by you:
- Open https://zeabur.com and sign in.
- Go to Settings → API Keys (Account section).
- Click Create Access Token, give it a description (e.g.
toolkit), pick an expiration (30 days by default), and create it.
- Copy the token immediately — it is shown only once.
- Store it — prefer the token file, which every session picks up automatically (an
export in the chat only lives in that one shell, and pasting the token into the conversation leaves it in the transcript):
mkdir -p ~/.config/zeabur
touch ~/.config/zeabur/toolkit-token && chmod 600 ~/.config/zeabur/toolkit-token
export ZEABUR_API_KEY="<token>"
Never write the token into any file that could be committed, and avoid having the user paste it into the chat — the transcript keeps it.
If neither the env var nor the token file exists but the Zeabur CLI is logged in on this machine (~/.config/zeabur/cli.yaml), you may offer to reuse that token — but say so before using it, never silently, and suggest saving it into the token file so future sessions are set.
Tokens currently have full account access (fine-grained scopes are coming). Treat it like a password: never print it, never log it, never send it to any host other than api.zeabur.com — and never copy it onto a rented server.
The standard API call pattern
Every Toolkit skill uses this pattern. The token goes into a chmod 600 curl config passed with -K, never as a -H argument on the command line (command-line arguments are visible in the process list):
TOKEN="${ZEABUR_API_KEY:-$([ -f ~/.config/zeabur/toolkit-token ] && cat ~/.config/zeabur/toolkit-token)}"
[ -n "$TOKEN" ] || { echo "No Zeabur token — set ZEABUR_API_KEY or create ~/.config/zeabur/toolkit-token (see the auth skill)" >&2; exit 1; }
ZAPI_CFG=$(mktemp)
chmod 600 "$ZAPI_CFG"
trap 'rm -f "$ZAPI_CFG"' EXIT
printf 'header = "Authorization: Bearer %s"\n' "$TOKEN" > "$ZAPI_CFG"
zapi() {
curl -sS -K "$ZAPI_CFG" -H "Content-Type: application/json" \
--data-binary "$1" https://api.zeabur.com/graphql
}
Always check the response for GraphQL errors before using data. When a response passes through a shell variable, print it with printf '%s\n', never echo — under sh/zsh, echo expands the \n escapes inside JSON strings (multi-line fields like resolvedDockerfile, failureSummary, or server events messages) into raw newlines, corrupting the JSON so jq fails with an "unescaped control character" error that looks like an API bug:
RESP=$(zapi '{"query":"{ me { username email } }"}')
printf '%s\n' "$RESP" | jq -e '.errors' >/dev/null && { printf '%s\n' "$RESP" | jq '.errors[].message' >&2; exit 1; }
printf '%s\n' "$RESP" | jq '.data.me'
Verifying access
The call above doubles as the verification: if it returns the user's username, the token works. If it returns an authentication error, the token is missing, expired, or revoked — create a new one via the steps above.
Team workspaces
Toolkit operations default to the user's personal workspace. Mutations and queries that support team resources take an optional ownerID argument (the team ID) — pass it only when the user explicitly wants to operate on a team's resources.