Beehiiv Integration Setup Guide

This document outlines all the work required to complete the Beehiiv cross-posting integration.

Current Status

COMPLETED:

  • Beehiiv subscribe form integrated on GitHub Pages site
  • RSS feed removed from site
  • Sync script created (scripts/sync_to_beehiiv.py)
  • GitHub Actions workflow created (.github/workflows/beehiiv-sync.yml)
  • Dependencies file created (scripts/requirements.txt)
  • Documentation created (scripts/README.md)

PENDING: API access and configuration (see below)


Required Work

1. Request Beehiiv Enterprise API Access

Status: ⏳ NOT STARTED

Action Required:

  1. Log into your Beehiiv dashboard
  2. Navigate to Help page or click the Chatbot Assistant
  3. Send message requesting Enterprise API access:
    Hi, I'd like to request access to the Beehiiv Send API / Create Post endpoint.
    I want to programmatically cross-post content from my Jekyll blog to Beehiiv.
    
  4. Wait for response from Beehiiv support
  5. Once approved, obtain:
    • API key
    • Publication ID

Resources:

Expected Timeline: Days to weeks (depends on Beehiiv support response time)

Blockers: Cannot proceed with remaining steps until API access is granted


2. Verify API Endpoint and Payload Structure

Status: ⏳ BLOCKED (waiting for API access)

Action Required:

Once you have API access, verify these details in the sync script:

File: scripts/sync_to_beehiiv.py

Search for # TODO: comments and verify:

a) API Base URL (Line ~36)

# TODO: Verify API endpoint URL with Beehiiv documentation once you have API access
API_BASE_URL = 'https://api.beehiiv.com/v2'
  • Check: Is https://api.beehiiv.com/v2 the correct base URL?
  • Reference: Beehiiv API documentation

b) Request Payload Field Names (Lines ~212-237)

# TODO: Verify these field names match actual Beehiiv API specification
payload = {
    "title": post_data['title'],
    "status": "confirmed",
    "platform": "both",
    "content": {
        "html": html_content
    }
}

Verify these field names are correct:

  • title - Post title
  • status - Publication status (“confirmed” for immediate publish)
  • platform - Where to publish (“both” for email + web)
  • content.html - HTML content structure
  • subtitle - Excerpt/subtitle field name
  • content_tags - Tags field name
  • web_url_override - Canonical URL field name
  • send_at - Publish date field name and format

c) Response Structure (Line ~250)

# TODO: Verify response structure with actual API - adjust path to post ID if needed
post_id = result.get('id') or result.get('data', {}).get('id')
  • Check: Where is the post ID in the API response?
  • Adjust code if the post ID is at a different path

d) Date Format (Line ~236)

# TODO: Verify date format expected by Beehiiv (ISO 8601 assumed)
payload["send_at"] = post_data['date']
  • Check: Does Beehiiv expect ISO 8601 format? (e.g., “2025-04-13T10:00:00Z”)
  • Adjust if different format needed

Testing Method:

  1. Make a test API call with curl or Postman
  2. Verify request/response structure
  3. Update script if needed
  4. Run local test (see Testing section below)

3. Configure GitHub Secrets

Status: ⏳ BLOCKED (waiting for API access)

Action Required:

  1. Go to your GitHub repository: https://github.com/m-01101101/mrogers-london
  2. Navigate to: SettingsSecrets and variablesActions
  3. Click New repository secret
  4. Add two secrets:

Secret 1: BEEHIIV_API_KEY

  • Name: BEEHIIV_API_KEY
  • Value: Your API key from Beehiiv (obtained in step 1)

Secret 2: BEEHIIV_PUBLICATION_ID

  • Name: BEEHIIV_PUBLICATION_ID
  • Value: Your publication ID from Beehiiv

How to find Publication ID:

  • Check Beehiiv dashboard URL (may be in the URL)
  • Check API documentation
  • Contact Beehiiv support if unclear

Documentation:


4. Local Testing (Before Deployment)

Status: ⏳ BLOCKED (waiting for API access and secrets)

Action Required:

Test the sync script locally before deploying to GitHub Actions:

# Navigate to repo directory
cd /Users/michael/m-01101101/mrogers-london

# Set environment variables
export BEEHIIV_API_KEY="your_actual_api_key_here"
export BEEHIIV_PUBLICATION_ID="your_actual_publication_id_here"

# Install dependencies
pip install -r scripts/requirements.txt

# Run sync script
python scripts/sync_to_beehiiv.py

Expected Outcome:

  • Script finds 5 posts in _posts/
  • Each post is converted to HTML
  • Posts are created on Beehiiv via API
  • State file .beehiiv_sync_state.json is created
  • No errors in output

If errors occur:

  1. Check API endpoint URL
  2. Verify payload field names
  3. Check response parsing logic
  4. Review error messages for hints
  5. Update script as needed

Validation:

  • Script runs without errors
  • 5 posts created on Beehiiv
  • Posts have correct titles, dates, content
  • Images load correctly (absolute URLs to mrogers.london)
  • State file created with all posts tracked

5. Initial Backfill via GitHub Actions

Status: ⏳ BLOCKED (waiting for local testing to pass)

Action Required:

Once local testing succeeds, trigger the GitHub Actions workflow:

Method 1: Manual Trigger

  1. Go to GitHub repo → Actions tab
  2. Select “Sync to Beehiiv” workflow
  3. Click “Run workflow”
  4. Select branch: main
  5. Click “Run workflow” button

Method 2: Automatic Trigger

  1. Make any commit to _posts/ directory
  2. Push to main branch
  3. Workflow triggers automatically

Validation:

  • Workflow runs successfully (green checkmark)
  • No errors in workflow logs
  • All 5 posts appear on Beehiiv
  • State file (.beehiiv_sync_state.json) committed to repo
  • State file contains all 5 posts

If workflow fails:

  1. Check workflow logs in GitHub Actions
  2. Verify GitHub Secrets are set correctly
  3. Check for API errors in logs
  4. Debug and re-run

6. Enable “Remove Indexing” on Beehiiv

Status: ⏳ BLOCKED (waiting for successful backfill)

Action Required:

After posts are successfully syncing to Beehiiv:

  1. Log into Beehiiv dashboard
  2. Navigate to: SettingsPublication Settings
  3. Find setting: “Remove Indexing” or “Disable Indexing”
  4. Toggle it ON

Why: This prevents Google from indexing your Beehiiv site, avoiding duplicate content SEO issues. Your primary site (mrogers.london) remains the SEO-indexed version.

Important: Only do this AFTER you verify posts are syncing correctly. If you enable this too early, you won’t be able to check if posts appear on Beehiiv web.

Validation:

  • Setting enabled in Beehiiv
  • Beehiiv posts still accessible to subscribers (not publicly indexed)
  • mrogers.london remains Google-indexed

Reference:


7. Test End-to-End Workflow

Status: ⏳ BLOCKED (waiting for all above steps)

Action Required:

Create a test post to verify the full workflow:

# Create a test post
cat > _posts/2025-12-28-test-post.md <<'EOF'
---
title: "Test Post - Delete Me"
date: 2025-12-28
type: essay
excerpt: "This is a test post to verify Beehiiv integration."
tags: [test]
---

This is a test post to verify that:
- Markdown converts to HTML
- Images work correctly: ![Test](/assets/images/avatar.jpg)
- Cross-posting works automatically

You can delete this post after verification.
EOF

# Commit and push
git add _posts/2025-12-28-test-post.md
git commit -m "Test: Beehiiv integration"
git push origin main

Expected Behavior:

  1. GitHub Actions workflow triggers automatically
  2. Script detects new post
  3. Post created on Beehiiv (web + email)
  4. State file updated and committed
  5. Post appears on both mrogers.london and Beehiiv

Validation Checklist:

  • Post appears on mrogers.london
  • Post appears on Beehiiv web
  • Email sent to subscribers (check your inbox)
  • Images load correctly in Beehiiv
  • Canonical URL links back to mrogers.london
  • State file updated in repo
  • Workflow completed successfully (green checkmark)

Clean Up: After successful test, delete the test post:

git rm _posts/2025-12-28-test-post.md
git commit -m "Remove test post"
git push origin main

Quick Reference: All TODO Items in Code

Search for # TODO: in these files:

scripts/sync_to_beehiiv.py

  1. Line ~27: Set BEEHIIV_API_KEY and BEEHIIV_PUBLICATION_ID in GitHub Secrets
  2. Line ~35: Verify API base URL
  3. Line ~212: Verify request payload field names
  4. Line ~224: Verify optional field names (subtitle, tags, canonical URL)
  5. Line ~236: Verify date format
  6. Line ~250: Verify response structure (post ID location)

Troubleshooting

API Access Issues

Problem: Beehiiv hasn’t responded to API access request

Solution:

  • Follow up with support after 3-5 business days
  • Check spam folder for email response
  • Try reaching out via different channel (email vs. chat)

Authentication Errors

Problem: Authentication failed. Check BEEHIIV_API_KEY

Solutions:

  • Verify API key is correctly copied (no extra spaces)
  • Check GitHub Secret name matches exactly: BEEHIIV_API_KEY
  • Confirm you have Enterprise API access (not just regular account)

Field Name Errors

Problem: Validation error or Unknown field from API

Solutions:

  • Review Beehiiv API documentation for correct field names
  • Update payload structure in sync_to_beehiiv.py
  • Test with minimal payload first, then add optional fields

Posts Not Appearing

Problem: Script runs without errors but posts don’t appear on Beehiiv

Possible Causes:

  • Posts created as drafts instead of published (check status field)
  • Posts scheduled for future date (check send_at field)
  • Posts on Beehiiv but not visible due to permissions

Solutions:

  • Check Beehiiv dashboard for draft posts
  • Verify status: "confirmed" in payload
  • Check send_at is not in the future

Timeline Estimate

Task Time Required Depends On
1. Request API access 1 hour work, days/weeks wait -
2. Verify API details 1-2 hours Task 1
3. Configure GitHub Secrets 10 minutes Task 1
4. Local testing 30-60 minutes Tasks 2, 3
5. Initial backfill 15 minutes Task 4
6. Enable “Remove Indexing” 5 minutes Task 5
7. End-to-end testing 30 minutes Tasks 1-6

Total Active Work: 3-5 hours Total Calendar Time: Days to weeks (waiting for API access)


Support Resources

Beehiiv Documentation:

  • API Getting Started: https://developers.beehiiv.com/welcome/getting-started
  • Create Post: https://developers.beehiiv.com/api-reference/posts/create
  • Send API Guide: https://beehiivhelp.zendesk.com/hc/en-us/articles/36759164012439

GitHub Documentation:

  • Actions: https://docs.github.com/en/actions
  • Secrets: https://docs.github.com/en/actions/security-guides/encrypted-secrets

Project Documentation:

  • Script README: scripts/README.md
  • Plan Document: .claude/plans/nested-greeting-wirth.md

Getting Help:

  • Beehiiv API issues → Contact Beehiiv support
  • Script errors → Check script logs, review TODOs
  • GitHub Actions issues → Check workflow logs

Success Criteria

You’ll know the integration is complete when:

✅ All 5 existing posts cross-posted to Beehiiv ✅ New posts automatically sync within 5 minutes of push ✅ Images display correctly in Beehiiv ✅ No duplicate content SEO issues (“Remove Indexing” enabled) ✅ State file tracks all synced posts ✅ Zero manual work required for publishing


Next Steps

Start here:

  1. Request Beehiiv Enterprise API access (Task #1 above)
  2. Wait for approval
  3. Return to this document and continue with Task #2

Track your progress: Check off items as you complete them.