Examples and use cases

Practical examples for common API workflows.

Publish a single page

The simplest case. Create a page and build in one request:

curl -X POST https://sitepaste.com/api/v1/public/pages \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "pages": [
      {
        "title": "Hello world",
        "content": "# Hello world\n\nMy first post via the API.",
        "tags": ["intro"]
      }
    ],
    "build": true
  }'

Batch publish documentation

Send all your docs pages in a single request. Each page uses upsert semantics, so running this repeatedly only updates what changed.

curl -X POST https://sitepaste.com/api/v1/public/pages \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "pages": [
      {
        "slug": "getting-started",
        "title": "Getting started",
        "content": "# Getting started\n\nInstall with npm...",
        "contentType": "docs"
      },
      {
        "slug": "configuration",
        "title": "Configuration",
        "content": "# Configuration\n\nEdit config.json...",
        "contentType": "docs"
      },
      {
        "slug": "api-reference",
        "title": "API reference",
        "content": "# API reference\n\nEndpoints...",
        "contentType": "docs"
      }
    ],
    "build": true
  }'

Publish pages with sections

Use the section field to group pages within a content type. Pages with a section appear at URLs like /docs/guides/getting-started:

curl -X POST https://sitepaste.com/api/v1/public/pages \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "pages": [
      {
        "slug": "getting-started",
        "title": "Getting started",
        "content": "# Getting started\n\nFollow these steps...",
        "contentType": "docs",
        "section": "guides"
      },
      {
        "slug": "deployment",
        "title": "Deployment",
        "content": "# Deployment\n\nDeploy your site...",
        "contentType": "docs",
        "section": "guides"
      }
    ],
    "build": true
  }'

The same slug can exist in different sections or content types. For example, a page at /docs/guides/overview and /docs/tutorials/overview are separate pages.

Update a single field

Change just the draft status of a page without touching anything else:

curl -X POST https://sitepaste.com/api/v1/public/pages \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"pages": [{"slug": "my-draft", "draft": false}]}'

Rename a slug

Use the page ID to change its slug. Get the ID from GET /pages first:

curl -X POST https://sitepaste.com/api/v1/public/pages \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"pages": [{"id": "a1b2c3d4-...", "slug": "better-slug"}]}'

Upload a photo with a page

Attach an image to a page using multipart form data and file: references:

curl -X POST https://sitepaste.com/api/v1/public/pages \
  -H "Authorization: Bearer $TOKEN" \
  -F payload='{"pages": [{"title": "Beach day", "content": "Great day at the beach.\n\n![sunset](file:sunset.jpg)", "tags": ["photos"]}], "build": true}' \
  -F files=@sunset.jpg

Sync and clean up

Use deleteSlugs to remove old pages while adding new ones in a single atomic operation. Each deletion entry requires a slug and contentType, and optionally a section if the page belongs to one:

curl -X POST https://sitepaste.com/api/v1/public/pages \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "pages": [
      {"slug": "v2-intro", "title": "Introduction (v2)", "content": "...", "contentType": "docs"}
    ],
    "deleteSlugs": [
      {"slug": "v1-intro", "contentType": "docs"},
      {"slug": "v1-getting-started", "contentType": "docs", "section": "guides"}
    ],
    "build": true
  }'

Diff-based sync with GET /pages

List remote pages and compare them to local files to publish only what changed:

# Get remote page metadata
curl -s https://sitepaste.com/api/v1/public/pages \
  -H "Authorization: Bearer $TOKEN" | jq '.pages[] | {slug, updatedAt}'

Use the id and updatedAt fields to determine which local files need to be pushed and which remote pages need to be deleted.

Poll build completion

Trigger a build and wait for it to finish:

# Trigger build
curl -s -X POST https://sitepaste.com/api/v1/public/builds \
  -H "Authorization: Bearer $TOKEN"

# Poll until done
while true; do
  RESULT=$(curl -s https://sitepaste.com/api/v1/public/builds/latest \
    -H "Authorization: Bearer $TOKEN")
  STATUS=$(echo "$RESULT" | jq -r '.status')
  echo "Build status: $STATUS"
  if [ "$STATUS" = "success" ] || [ "$STATUS" = "failed" ]; then
    break
  fi
  sleep 2
done

GitHub Actions

Use the official deploy action to publish markdown files when changes are pushed to main:

name: Deploy docs

on:
  push:
    branches: [main]
    paths: [docs/**]

concurrency:
  group: sitepaste-deploy-${{ github.ref }}
  cancel-in-progress: true

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: Sitepaste/integrations/actions/deploy@v1
        with:
          api-token: ${{ secrets.SITEPASTE_TOKEN }}
          content-dir: docs
          content-type: docs

The action parses front matter, slugifies filenames, validates all pages locally, then syncs them in a single batch request and triggers a build. See the full integration docs for all inputs, outputs, and additional examples.

iPhone shortcut

Create a shortcut to publish from your phone:

  1. Add “Get contents of URL” action
  2. Set URL to https://sitepaste.com/api/v1/public/pages
  3. Set method to POST
  4. Add header Authorization with value Bearer sp_your_token_here
  5. Add header Content-Type with value application/json
  6. Set request body to JSON:
{
  "pages": [
    {
      "title": "Ask for input",
      "content": "Ask for input"
    }
  ],
  "build": true
}

Use the “Ask for input” action in the shortcut to prompt for the title and content dynamically.

For photo posts, use multipart form data. Add the photo as a file field and reference it with file:photo.jpg in the content.

Upload media separately

Upload a file first, then use the URL in your page content:

# Upload the image
RESPONSE=$(curl -s -X POST https://sitepaste.com/api/v1/public/media \
  -H "Authorization: Bearer $TOKEN" \
  -F file=@header.jpg)

URL=$(echo "$RESPONSE" | jq -r '.url')

# Create a page with the uploaded image
curl -X POST https://sitepaste.com/api/v1/public/pages \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{
    \"pages\": [{
      \"title\": \"Post with header image\",
      \"content\": \"![Header]($URL)\n\nWelcome to my post.\"
    }],
    \"build\": true
  }"

Delete a page

The contentType query parameter is required. Include section if the page belongs to one:

curl -X DELETE "https://sitepaste.com/api/v1/public/pages/old-post?contentType=blog" \
  -H "Authorization: Bearer $TOKEN"

Returns 204 on success, 404 if the page does not exist.