curl fallback

Publish with plain HTTP.

Use this path from any machine that can run curl. The exact request schema lives in OpenAPI, but this page is the safest fallback when no skill is available.

Flow

  1. Create a publish session with POST /api/publish.
  2. Upload each file to its returned uploadTargets[].url using the returned method and headers exactly.
  3. Record each uploaded file with POST /api/publish/{publishSessionId}/uploads.
  4. Finalize the session with POST /api/publish/{publishSessionId}/finalize.
  5. Use the returned URL, slug, and management links.

Minimal one-file example

BASE="${PUBTHIS_BASE_URL:-https://pubthis.net}"
printf '<h1>Hello from pubthis.net</h1>\n' > index.html
SHA="$(sha256sum index.html | awk '{print $1}')"
SIZE="$(wc -c < index.html | tr -d ' ')"
CREATE="$(curl -fsS -X POST "$BASE/api/publish" \
  -H 'content-type: application/json' \
  -d "{\"mode\":\"create\",\"authMode\":\"anonymous\",\"files\":[{\"path\":\"index.html\",\"contentType\":\"text/html\",\"sizeBytes\":$SIZE,\"sha256\":\"$SHA\"}]}")"
SESSION="$(printf '%s' "$CREATE" | python -c 'import json,sys; print(json.load(sys.stdin)["publishSessionId"])')"
UPLOAD_URL="$(printf '%s' "$CREATE" | python -c 'import json,sys; print(json.load(sys.stdin)["uploadTargets"][0]["url"])')"
METHOD="$(printf '%s' "$CREATE" | python -c 'import json,sys; print(json.load(sys.stdin)["uploadTargets"][0]["method"])')"
curl -fsS -X "$METHOD" "$UPLOAD_URL" -H 'content-type: text/html' --data-binary @index.html
curl -fsS -X POST "$BASE/api/publish/$SESSION/uploads" \
  -H 'content-type: application/json' \
  -d "{\"publishSessionId\":\"$SESSION\",\"path\":\"index.html\",\"objectKey\":\"uploads/$SESSION/index.html\",\"sha256\":\"$SHA\",\"sizeBytes\":$SIZE}"
curl -fsS -X POST "$BASE/api/publish/$SESSION/finalize" \
  -H 'content-type: application/json' \
  -d "{\"publishSessionId\":\"$SESSION\",\"files\":[{\"path\":\"index.html\",\"sha256\":\"$SHA\"}]}"

Share roots

Use the URL returned by finalize as the root. Subdomain deployments serve files at the returned host, so a file path becomes {returnedUrl}/path/to/file. Path-based /{slug}/... URLs are compatibility redirects, not the canonical share root.

Slug requirements

Anonymous publishing must omit slug. Custom slugs require authMode "api_key" and Authorization: Bearer <PUBTHIS_API_KEY>; anonymous custom slug requests return custom_slug_requires_auth.

Publish slugs must be DNS-safe single labels: lower-case a-z, 0-9, or hyphen; 1-63 characters; no dots, underscores, spaces, or leading/trailing hyphens. Omit slug to let pubthis.net choose a human-readable four-word pet name with a three-character suffix.

Update an existing Site

Reuse the slug returned by a previous publish. If the API returns a stable error code, branch on code rather than message text.