Cursor Rules for PageGun

Add PageGun to your Cursor IDE with rule files. Cursor's AI gets full context on the PageGun API — create pages, manage docs, configure navigation, and publish without looking anything up.

Quick Setup

  1. Create .cursor/rules/ in your project root (if it doesn't exist)
  2. Copy the rule files below into that folder
  3. Set your API key:
export PAGEGUN_API_KEY="pgk_live_your_key_here"

Rule Files

We provide three rule files — use the ones you need:

FilePurposeWhen to Use
pagegun.mdcCore API — projects, pages, media, subroutes, navigationAlways
pagegun-docs.mdcDocs pages — markdown, cards, callouts, steps, code tabsWhen managing documentation sites
pagegun-blog.mdcBlog/articles — create, publish, manage blog postsWhen managing blog content

pagegun.mdc — Core API

Covers all endpoints: projects, pages, docs, subroutes, navigation, media, settings.

Save as .cursor/rules/pagegun.mdc:

---
description: Manage PageGun sites — create pages, manage docs & navigation, upload images, publish. Use when working with PageGun API or managing web content.
globs: 
alwaysApply: false
---

# PageGun API Integration

You can manage PageGun sites via the REST API. Use `curl` or `fetch` to interact with pages, docs, media, subroutes, and navigation.

## Setup

API key should be set as environment variable:

```bash
export PAGEGUN_API_KEY="pgk_live_your_key_here"
```

## Base URL

```
https://api.pagegun.com
```

All requests require `Authorization: Bearer $PAGEGUN_API_KEY` header.
All endpoints require `?project_id=xxx` query parameter.

## Endpoints

### Projects

| Method | Path | Description |
|--------|------|-------------|
| GET | /projects | List all projects |
| GET | /projects/:id | Get a project |
| PUT | /projects/:id | Update a project |

### Pages (Landing Pages, Articles)

| Method | Path | Description |
|--------|------|-------------|
| GET | /pages?project_id=xxx | List pages |
| POST | /pages | Create a page |
| GET | /pages/:id | Get a page |
| PUT | /pages/:id | Update a page |
| POST | /pages/:id/publish | Publish a page |
| POST | /pages/:id/unpublish | Unpublish a page |

### Docs

| Method | Path | Description |
|--------|------|-------------|
| GET | /docs?project_id=xxx | List docs |
| POST | /docs | Create a doc page |
| GET | /docs/:id | Get a doc (includes nav_context) |
| PUT | /docs/:id | Update a doc |

> **Important:** Create/update docs with `/docs`, but publish with `/pages/:id/publish`.

### Subroutes

| Method | Path | Description |
|--------|------|-------------|
| POST | /subroutes?project_id=xxx | Create a subroute |
| GET | /subroutes?project_id=xxx | List subroutes |
| GET | /subroutes/:slug?project_id=xxx | Get a subroute |
| PUT | /subroutes/:slug?project_id=xxx | Update subroute (nav change re-publishes sidebar) |
| DELETE | /subroutes/:slug?project_id=xxx | Delete a subroute |
| GET | /subroutes/:slug/pages?project_id=xxx | List pages in subroute |

### Media

| Method | Path | Description |
|--------|------|-------------|
| POST | /media | Upload media (form-data) |
| POST | /media | Upload from URL (JSON) |
| DELETE | /media/:id | Delete media |

### Settings

| Method | Path | Description |
|--------|------|-------------|
| GET | /projects/:id/settings | Get project settings |
| PUT | /projects/:id/settings | Update settings |

## Which Endpoint for Which Page Type?

| Type | Create | Update | Publish |
|------|--------|--------|---------|
| Landing page | `POST /pages` | `PUT /pages/:id` | `POST /pages/:id/publish` |
| Article/Blog | `POST /pages` | `PUT /pages/:id` | `POST /pages/:id/publish` |
| **Docs** | **`POST /docs`** | **`PUT /docs/:id`** | `POST /pages/:id/publish` |
| Item | `POST /pages` | `PUT /pages/:id` | `POST /pages/:id/publish` |

> **Best practice:** Always use `/docs` for documentation pages. It auto-sets `type: "docs"` and `subroute: "docs"`, validates markdown, and returns `nav_context`.

## Creating a Docs Page

```bash
curl -X POST "$BASE/docs?project_id=$PID" \
  -H "Authorization: Bearer $PAGEGUN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Authentication",
    "slug": "api/authentication",
    "markdown_content": "# Authentication\n\nOur API uses Bearer tokens..."
  }'
```

Only 3 required fields: `title`, `markdown_content`, `project_id`.

Slugs support nesting with `/` — e.g. `api/authentication`, `guides/webhooks`, `agents/best-practices`.

## Creating a Landing Page

```bash
curl -X POST "$BASE/pages" \
  -H "Authorization: Bearer $PAGEGUN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "page_name": "My Page",
    "slug": "my-page",
    "subroute": "page",
    "type": "page",
    "project_id": "YOUR_PROJECT_ID",
    "config": {"sections": []}
  }'
```

## Managing Navigation (Subroutes)

Navigation controls the docs sidebar. Set it on a subroute — three modes available:

### Create subroute with navigation

```bash
curl -X POST "$BASE/subroutes?project_id=$PID" \
  -H "Authorization: Bearer $PAGEGUN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "docs",
    "name": "Documentation",
    "navigation": {
      "groups": [
        {"group": "Getting Started", "pages": ["overview", "quickstart", "installation"]},
        {"group": "API Reference", "pages": [
          "api/overview",
          {"group": "Endpoints", "pages": ["api/pages", "api/projects", "api/media"]}
        ]}
      ]
    }
  }'
```

### Navigation modes

**Groups** — Simple sidebar with collapsible groups:
```json
{"groups": [{"group": "Title", "pages": ["slug1", "slug2"]}]}
```

**Tabs** — Horizontal tab bar at top (Stripe Docs style):
```json
{"tabs": [{"tab": "Docs", "icon": "book", "groups": [...]}, {"tab": "API", "icon": "code", "groups": [...]}]}
```

**Anchors** — Sidebar top icons (Resend style):
```json
{"anchors": [{"anchor": "Docs", "icon": "book", "groups": [...]}, {"anchor": "Discord", "icon": "chat", "href": "https://..."}]}
```

### Update navigation

```bash
curl -X PUT "$BASE/subroutes/docs?project_id=$PID" \
  -H "Authorization: Bearer $PAGEGUN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"navigation": {"groups": [...]}}'
```

Updating navigation automatically re-publishes the sidebar to CDN.

### Group options

| Field | Type | Description |
|-------|------|-------------|
| `group` | string | Group title in sidebar |
| `icon` | string | Icon name (optional) |
| `root` | string | Page slug when clicking group title |
| `expanded` | boolean | Default expanded state |
| `pages` | array | Page slugs or nested group objects |

### Nesting

Pages array can mix slugs and sub-groups:
```json
{"group": "API", "pages": ["overview", {"group": "Pages", "pages": ["create", "get", "list"]}]}
```

### Page ordering

Array order = sidebar order. Reorder by rearranging the `pages` array.

### Unlisted pages

Pages not in the navigation tree are still accessible by URL — just hidden from the sidebar.

## Complete Workflow: Build a Docs Site

```bash
# 1. Create pages
ID1=$(curl -s -X POST "$BASE/docs?project_id=$PID" -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"Overview","slug":"overview","markdown_content":"# Overview\n..."}' | jq -r .id)

ID2=$(curl -s -X POST "$BASE/docs?project_id=$PID" -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"Quick Start","slug":"quickstart","markdown_content":"# Quick Start\n..."}' | jq -r .id)

# 2. Create subroute with navigation
curl -s -X POST "$BASE/subroutes?project_id=$PID" -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"slug":"docs","name":"Documentation","navigation":{"groups":[{"group":"Docs","pages":["overview","quickstart"]}]}}'

# 3. Publish pages
curl -s -X POST "$BASE/pages/$ID1/publish?project_id=$PID" -H "Authorization: Bearer $KEY"
curl -s -X POST "$BASE/pages/$ID2/publish?project_id=$PID" -H "Authorization: Bearer $KEY"
```

## Uploading Images

### From URL
```bash
curl -X POST "$BASE/media" \
  -H "Authorization: Bearer $PAGEGUN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/image.png", "project_id": "xxx", "alt_text": "Screenshot"}'
```

### From file
```bash
curl -X POST "$BASE/media" \
  -H "Authorization: Bearer $PAGEGUN_API_KEY" \
  -F "file=@./screenshot.png" \
  -F "project_id=xxx" \
  -F "alt_text=Screenshot"
```

## Error Format

```json
{"statusCode": 422, "name": "validation_error", "message": "title must be a non-empty string"}
```

Common codes: 200 (OK), 201 (Created), 400 (Bad request), 401 (Unauthorized), 404 (Not found), 422 (Validation), 429 (Rate limited)

Rate limit: 100 requests per minute per API key.

## ⚠️ Safety: Read Before Write

**This API operates directly on production. There is no undo.**

1. Always `GET` first to see current content before updating
2. Show the user what you plan to change and get confirmation
3. After updating, verify before publishing
4. Never blindly overwrite

## Important Notes

- **Deletion is NOT allowed via API key** — use the dashboard
- After updating content, **always re-publish** to push changes to CDN
- Docs: create/update with `/docs`, publish with `/pages/:id/publish`
- Navigation update on subroute automatically re-publishes sidebar

What You Can Ask Cursor (Core)

  • "List all my PageGun projects"
  • "Create a new docs page about webhooks"
  • "Set up navigation for my docs site"
  • "Add a new group to the sidebar"
  • "Upload this image and use it in my page"
  • "Reorder the sidebar navigation"

pagegun-docs.mdc — Documentation Pages

Covers docs-specific features: cards, callouts, steps, code tabs, nested slugs, and image handling in markdown.

Save as .cursor/rules/pagegun-docs.mdc:

---
description: Write and manage PageGun documentation pages — create docs with cards, callouts, steps, code tabs, and images. Use when working with docs-type pages on PageGun.
globs: 
alwaysApply: false
---

# PageGun Docs Pages

This rule covers **docs-type pages** on PageGun — documentation sites with sidebar navigation, rich markdown, and interactive components.

## Creating Docs

Use the **Docs API** (not Pages API) for documentation:

```bash
curl -X POST "https://api.pagegun.com/docs?project_id=YOUR_PROJECT_ID" \
  -H "Authorization: Bearer $PAGEGUN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Authentication",
    "slug": "api/authentication",
    "markdown_content": "# Authentication\n\nOur API uses Bearer tokens..."
  }'
```

**Required fields:** `title`, `markdown_content`, `project_id`
**Optional fields:** `slug`, `description`, `og_image_url`, `locale`

The Docs API automatically sets `type: "docs"` and `subroute: "docs"`.

### Nested slugs

Slugs support `/` for hierarchy — use this to organize content:

```
overview                    → /docs/overview
quickstart                  → /docs/quickstart
api/authentication          → /docs/api/authentication
api/pages/create            → /docs/api/pages/create
guides/webhooks/setup       → /docs/guides/webhooks/setup
agents/best-practices       → /docs/agents/best-practices
```

No depth limit. Slug structure is independent of navigation — a page at `agents/deep/nested/page` can appear in any nav group.

### Update a doc

```bash
curl -X PUT "https://api.pagegun.com/docs/PAGE_ID?project_id=YOUR_PROJECT_ID" \
  -H "Authorization: Bearer $PAGEGUN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Updated Title",
    "markdown_content": "# Updated content..."
  }'
```

### Publish a doc

```bash
curl -X POST "https://api.pagegun.com/pages/PAGE_ID/publish?project_id=YOUR_PROJECT_ID" \
  -H "Authorization: Bearer $PAGEGUN_API_KEY"
```

> Note: Publish uses `/pages/:id/publish`, not `/docs/:id/publish`.

### Get a doc (with nav context)

```bash
curl "https://api.pagegun.com/docs/PAGE_ID?project_id=YOUR_PROJECT_ID" \
  -H "Authorization: Bearer $PAGEGUN_API_KEY"
```

Returns the doc plus `nav_context` — a list of all other docs in the project. Useful for building navigation or checking what pages exist.

## Managing Navigation

After creating docs pages, set up the sidebar via subroutes:

```bash
# Create or update navigation
curl -X PUT "https://api.pagegun.com/subroutes/docs?project_id=YOUR_PROJECT_ID" \
  -H "Authorization: Bearer $PAGEGUN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "navigation": {
      "groups": [
        {"group": "Getting Started", "pages": ["overview", "quickstart"]},
        {"group": "API Reference", "pages": [
          "api/overview",
          {"group": "Pages", "pages": ["api/pages/create", "api/pages/get"]},
          {"group": "Projects", "pages": ["api/projects/get", "api/projects/list"]}
        ]},
        {"group": "Guides", "pages": ["guides/webhooks", "guides/custom-domains"]}
      ]
    }
  }'
```

Pages appear in sidebar in array order. Titles are resolved automatically from published pages.

## Markdown Components

Docs pages support standard markdown plus these special directives:

### Cards

Display navigation cards in a 2-column grid:

```markdown
:::cards
- title: Quick Start
  href: /docs/quick-start
  description: Get up and running in 5 minutes
  icon: rocket
- title: API Reference
  href: /docs/api
  description: Complete endpoint documentation
  icon: code
:::
```

**Icons:** `rocket`, `code`, `book`, `zap`, `shield`, `globe`, `settings`, `mail`, `file-text`, `database`, `key`, `webhook`, `layout`, `palette`, `search`, `terminal`, `server`, `users`, `credit-card`, `bar-chart`

### Callouts

```markdown
:::callout{type="info"}
This is an informational note.
:::

:::callout{type="warning"}
Be careful — this cannot be undone.
:::

:::callout{type="tip"}
Use project-scoped API keys for better security.
:::
```

Types: `info`, `warning`, `tip`

### Steps

````markdown
:::steps
### Create an API Key

Go to Settings → API Keys and click "Create".

### Set Your API Key

```bash
export PAGEGUN_API_KEY="pgk_live_your_key_here"
```

### Make Your First Request

```bash
curl https://api.pagegun.com/projects \
  -H "Authorization: Bearer $PAGEGUN_API_KEY"
```
:::
````

### Code Tabs

````markdown
:::code-tabs
```bash
curl "https://api.pagegun.com/pages" \
  -H "Authorization: Bearer $PAGEGUN_API_KEY"
```

```javascript
const res = await fetch('https://api.pagegun.com/pages', {
  headers: { 'Authorization': `Bearer ${API_KEY}` },
});
```

```python
import requests
res = requests.get(
    'https://api.pagegun.com/pages',
    headers={'Authorization': f'Bearer {API_KEY}'},
)
```
:::
````

## Images in Docs

```bash
# Upload
curl -X POST "https://api.pagegun.com/media" \
  -H "Authorization: Bearer $PAGEGUN_API_KEY" \
  -F "file=@./screenshot.png" \
  -F "project_id=YOUR_PROJECT_ID" \
  -F "alt_text=Dashboard screenshot"

# Use in markdown
![Dashboard screenshot](RETURNED_URL_HERE)
```

## Best Practices

1. **Use `/docs` API** — not `/pages` — for all documentation pages
2. **Organize with nested slugs** — `api/pages/create` not `api-pages-create`
3. **Set navigation via subroutes** — don't rely on auto-generated nav
4. **Publish after every change** — content doesn't go live until published
5. **Set `description`** — used for SEO meta tags and social cards
6. **Use directives** — cards, callouts, steps make docs more scannable
7. **Read before write** — always GET current content before updating

## ⚠️ Safety: Read Before Write

**This API operates directly on production. There is no undo.**

1. Always `GET /docs/:id` first to see current content
2. Show the user what you plan to change
3. After updating, verify before publishing

pagegun-blog.mdc — Blog / Articles

Covers blog-specific workflows: creating articles with markdown, SEO fields, categories, publishing, and reading from CDN.

Save as .cursor/rules/pagegun-blog.mdc:

---
description: Manage blog articles on PageGun — create, update, publish, and read blog posts via API and CDN. Use when working with blog content, articles, or news pages.
globs:
alwaysApply: false
---

# PageGun Blog / Articles

This rule covers **article-type pages** on PageGun — blog posts with markdown content, SEO metadata, and CDN delivery.

## Article Fields

| Field | Required | Description |
|-------|----------|-------------|
| `title` | Yes | Article title |
| `slug` | Yes | URL path segment (lowercase, hyphens, 3-100 chars) |
| `subroute` | Yes | URL prefix, e.g. `"blog"` → `/blog/slug` |
| `type` | Yes | Must be `"article"` |
| `project_id` | Yes | Your project ID |
| `markdown_content` | Yes | Full article body in Markdown |
| `description` | No | SEO meta description (155 chars recommended) |
| `og_image_url` | No | Social sharing image (1200×630px recommended) |
| `categories` | No | Array of category strings, e.g. `["Tech", "Tutorial"]` |
| `og_image_url` | No | Social sharing / featured image (1200×630px). Upload via `POST /media` first |

## Create a Blog Post

```bash
curl -X POST "https://api.pagegun.com/pages" \
  -H "Authorization: Bearer $PAGEGUN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "How We Built Our AI Pipeline",
    "slug": "how-we-built-our-ai-pipeline",
    "subroute": "blog",
    "type": "article",
    "project_id": "YOUR_PROJECT_ID",
    "description": "A behind-the-scenes look at building our AI pipeline with modern tooling.",
    "og_image_url": "https://cdn.example.com/blog/ai-pipeline-og.jpg",
    "markdown_content": "# How We Built Our AI Pipeline\n\nIn this post, we share our journey...\n\n## Architecture\n\nWe chose a modular approach...\n\n## Key Takeaways\n\n- Start simple\n- Iterate fast\n- Measure everything",
    "config": {}
  }'

Publish

curl -X POST "https://api.pagegun.com/pages/PAGE_ID/publish" \ -H "Authorization: Bearer $PAGEGUN_API_KEY"

After publishing, the article is available on CDN (where {subroute} matches the value you set, e.g. blog):

  • Article: https://content.pagegun.com/{project_id}/{subroute}/{slug}.enc
  • Nav index: https://content.pagegun.com/{project_id}/nav.enc

Update a Blog Post

# 1. Get current content curl -s "https://api.pagegun.com/pages/PAGE_ID" \ -H "Authorization: Bearer $PAGEGUN_API_KEY" # 2. Update curl -X PUT "https://api.pagegun.com/pages/PAGE_ID" \ -H "Authorization: Bearer $PAGEGUN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Updated Title", "description": "Updated description for SEO.", "markdown_content": "# Updated Title\n\nNew content here..." }' # 3. Re-publish curl -X POST "https://api.pagegun.com/pages/PAGE_ID/publish" \ -H "Authorization: Bearer $PAGEGUN_API_KEY"

Reading from CDN (Data Mode)

Blog content is encrypted on CDN. Decrypt server-side with your Content Key.

Fetch article index

const res = await fetch( `https://content.pagegun.com/${PROJECT_ID}/nav.enc`, { next: { revalidate: 60 } } ); const encrypted = await res.text(); const nav = JSON.parse(decrypt(encrypted)); const blogPosts = nav.items .filter(item => item.subroute === 'blog') // adjust to your subroute .sort((a, b) => new Date(b.published_at) - new Date(a.published_at));

Fetch single article

const res = await fetch( `https://content.pagegun.com/${PROJECT_ID}/${SUBROUTE}/${slug}.enc`, { next: { revalidate: 60 } } ); const encrypted = await res.text(); const article = JSON.parse(decrypt(encrypted)); // article.title, article.markdown_content, article.description, etc.

Decryption (Node.js)

import crypto from 'crypto'; function decrypt(encrypted) { const [ivHex, authTagHex, ciphertext] = encrypted.split(':'); const key = Buffer.from(process.env.PAGEGUN_CONTENT_KEY, 'hex'); const decipher = crypto.createDecipheriv( 'aes-256-gcm', key, Buffer.from(ivHex, 'hex') ); decipher.setAuthTag(Buffer.from(authTagHex, 'hex')); let result = decipher.update(ciphertext, 'hex', 'utf8'); result += decipher.final('utf8'); return result; }

⚠️ Never expose your Content Key in client-side code. Always decrypt server-side.

Upload & Use Images

Upload an image first, then reference it in your article or as the OG image:

# Upload image curl -X POST "https://api.pagegun.com/media" \ -H "Authorization: Bearer $PAGEGUN_API_KEY" \ -F "file=@./cover.jpg" \ -F "project_id=YOUR_PROJECT_ID" \ -F "alt_text=Blog post cover image" # Response includes the hosted URL: # { "url": "https://fs.pagegun.com/p/PROJECT_ID/media/abc123.webp", ... }

Use the returned URL:

  • As featured/OG image: set og_image_url when creating or updating the page
  • In markdown content: ![Alt text](https://fs.pagegun.com/p/PROJECT_ID/media/abc123.webp)
# Update article with image curl -X PUT "https://api.pagegun.com/pages/PAGE_ID" \ -H "Authorization: Bearer $PAGEGUN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "og_image_url": "https://fs.pagegun.com/p/PROJECT_ID/media/abc123.webp" }'

Author Attribution

📝 The author field is coming soon. For now, if you need author info, include it in your markdown content:

# My Blog Post *By Jane Smith · March 5, 2026* Article content here...

Need structured author support (name, avatar, bio)? Contact the developer.

Supported Markdown

  • Headings (h1–h6)
  • Bold, italic, strikethrough
  • Ordered and unordered lists
  • Links and images
  • Code blocks with syntax highlighting
  • Tables
  • Blockquotes

SEO Best Practices

  1. Slug — use descriptive, keyword-rich slugs (how-to-build-ai-agents)
  2. Description — under 155 characters, include target keyword
  3. OG Image — 1200×630px for social sharing
  4. Headings — proper hierarchy (H1 → H2 → H3)
  5. Categories — consistent naming for filtering

What You Can Ask Cursor

  • "Create a blog post about our new feature launch"
  • "Update the SEO description on our latest article"
  • "List all published blog posts"
  • "Add categories to our existing articles"
  • "Upload an image and use it as the OG image for a blog post"


## Getting Your API Key

## Getting Your API Key

1. Go to your [PageGun Dashboard](https://www.pagegun.com/dashboard)
2. Select your project
3. Go to **Settings** → **API Keys**
4. Click **Create API Key**
5. Copy and save your key — it won't be shown again

## Tips

- Explore the [API Reference](/docs/api-reference) for full endpoint details
- Check [Managing Navigation](/docs/guides/navigation) for advanced nav setups
- Use [Data Mode](/docs/api-reference/data-mode) for encrypted CDN delivery
- Set up [Webhooks](/docs/guides/webhooks) for publish/update notifications

## More Integrations

We also have an [Official PageGun Skill](/docs/agents/skill) for AI agents (OpenClaw, Claude Code, etc.) and a [TypeScript SDK](/docs/sdks/typescript) for programmatic access.
© 2026 PageGun. All rights reserved.