For AI Agents & Developers

Pubby for AI Agents and Developers

Your agent builds great output. Structured reports, data visualizations, interactive tools, dynamically generated landing pages. And then, what? You log it to a file? Render it locally? There's a missing step between "agent produces HTML" and "user sees a real page." Pubby is that step.

One API call. HTML in, live URL out. Under 3 seconds.

The Problem

Every agent that produces HTML output faces the same dead end: there's nowhere built for the output to go. Options people try and why they fall short:

Data URI

Works in a browser, breaks in chat interfaces, unusable as a shareable link.

Self-hosted server

Requires infra you have to maintain and scale; overkill for output that might only be viewed once.

Vercel/Netlify CLI

Needs a Git repo, project config, and a build step that assumes your HTML is part of a larger project.

GitHub Gist

Raw HTML, not rendered; anyone clicking the link sees source code.

Email attachment

Renders inconsistently, can't be linked, can't be updated.

What you actually need is: send HTML, get a URL that renders the page. No surrounding ceremony.

How It Works

Pubby's publish endpoint accepts HTML (or a full file bundle) and returns a live URL. That's the entire API surface for the publish operation.

Request

POST https://api.pubby.au/publish
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

{
  "html": "<html><body><h1>Hello from my agent</h1></body></html>",
  "slug": "agent-output-001"
}

Response

{
  "url": "https://pubby.au/agent-output-001",
  "slug": "agent-output-001",
  "published_at": "2026-02-22T12:00:00Z"
}

The URL is live immediately. Not "eventually consistent." Immediately.

Code Examples

curl -X POST https://api.pubby.au/publish \
  -H "Authorization: Bearer $PUBBY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "<html><body><h1>Report</h1><p>Content here</p></body></html>",
    "slug": "my-report"
  }'

Typical AI Pipeline Integration

Here's a complete workflow pattern used by teams running HTML-generating agents:

User request
     ↓
LLM (Claude/GPT/Gemini)
  - Receives prompt + data
  - Generates structured HTML output
     ↓
Post-processing (optional)
  - Inject custom CSS
  - Add analytics snippet
  - Sanitize user-supplied content
     ↓
Pubby API: POST /publish
     ↓
Live URL returned
     ↓
Return URL to user / store in database / send in email

The whole cycle, from user request to live URL, takes 5-10 seconds depending on LLM latency. Pubby's contribution to that is under 3 seconds.

Batch Publishing

Need to publish 100 pages at once? Pubby handles it. The API supports parallel requests up to your plan's rate limit.

import asyncio
import httpx
import os

async def publish_batch(pages: list[dict]) -> list[str]:
    """
    pages: list of {"html": "...", "slug": "..."}
    Returns: list of live URLs
    """
    async with httpx.AsyncClient() as client:
        tasks = [
            client.post(
                "https://api.pubby.au/publish",
                headers={"Authorization": f"Bearer {os.environ['PUBBY_API_KEY']}"},
                json=page,
            )
            for page in pages
        ]
        responses = await asyncio.gather(*tasks)
        return [r.json()["url"] for r in responses]


# Generate 100 product pages
product_pages = [
    {
        "html": generate_product_page(product),
        "slug": f"product-{product['id']}",
    }
    for product in products
]

urls = asyncio.run(publish_batch(product_pages))
print(f"Published {len(urls)} pages")

Rate Limits

PlanPublishes / hourConcurrent requestsMax file size
Free60510MB bundle
Pro ($12/mo)6002050MB bundle
Teams ($25/mo)1,50050100MB bundle
Business ($45/mo)3,000+100+200MB bundle

Rate limits apply to publish operations only. Published pages have no traffic limits. Use the rate limit headers in API responses to implement backoff:

def publish_with_backoff(html: str, slug: str, max_retries: int = 3) -> str:
    for attempt in range(max_retries):
        response = requests.post(
            "https://api.pubby.au/publish",
            headers={"Authorization": f"Bearer {os.environ['PUBBY_API_KEY']}"},
            json={"html": html, "slug": slug},
        )
        
        if response.status_code == 429:
            retry_after = int(response.headers.get("Retry-After", 60))
            print(f"Rate limited. Waiting {retry_after}s...")
            time.sleep(retry_after)
            continue
            
        response.raise_for_status()
        return response.json()["url"]
    
    raise Exception("Max retries exceeded")

Managing Published Pages via API

Beyond publishing, the API lets you update and delete pages:

# Update an existing page (republish to same slug)
requests.post(
    "https://api.pubby.au/publish",
    headers={"Authorization": f"Bearer {os.environ['PUBBY_API_KEY']}"},
    json={"html": new_html, "slug": "existing-slug"},  # overwrites
)

# Delete a page
requests.delete(
    "https://api.pubby.au/pages/existing-slug",
    headers={"Authorization": f"Bearer {os.environ['PUBBY_API_KEY']}"},
)

# List published pages
pages = requests.get(
    "https://api.pubby.au/pages",
    headers={"Authorization": f"Bearer {os.environ['PUBBY_API_KEY']}"},
).json()

Why Pubby Specifically, Not a General Object Storage?

S3 and similar services can host static files. But you'd need to:

  • →Configure bucket policies for public access
  • →Set correct Content-Type headers per file
  • →Configure CORS headers
  • →Set up a CloudFront distribution for HTTPS and performance
  • →Manage SSL certificates
  • →Handle slug/path routing yourself

That's 2-4 hours of setup and ongoing infrastructure management. Pubby does all of it in the 3 seconds before it hands you back a URL.

Getting Your API Key

  1. 1Sign up at pubby.au
  2. 2Go to Settings > API Keys
  3. 3Create a key with a descriptive name (e.g., "my-agent-prod")
  4. 4Store it in your environment variables, not in your code

Rotate keys anytime from the dashboard. Each key can be given a label so you know which application is using it.