Connect beehiiv to Fondoo
beehiiv in Fondoo: what your AI agent can do with it, what to set up first, the permissions it needs and its limits.
In beehiiv open Settings → Workspace Settings → API (workspace Owner or Admin; beehiiv requires Stripe identity verification first), create an API key that can access the publication, and copy that publication's ID (pub_...) from the Publication ID section below the keys; one Fondoo connection covers one publication. API keys carry no finer permission scopes. Subscriber sync works on every plan within beehiiv's per-key limit (Free 30 requests/minute); creating draft posts needs the Max or Enterprise plan and confirming (sending) them the Pro, Max or Enterprise plan per beehiiv's Send API docs.
Official documentation: https://developers.beehiiv.com/api-reference
Use add_connection_key without fields for a signed, one-use secure paste page. Then call test_connection and inspect confirmed versus unknown permissions. Direct tool credentials carry a chat-log warning. list_connections never returns credentials.
Auth: api_key (Authorization: Bearer <key>; credential fields apiKey (secret) and publicationId (not secret, format pub_ + UUID)). Category: email. Required provider scopes: none for API keys (beehiiv's OAuth scopes such as subscriptions:write and posts:write do not apply to API keys); a key limited to other publications fails with 401/403/404.
Capabilities are discoverable with list_connector_manifests; invoke them through connector_action. Writes retain shared Fondoo scopes, approvals, dry runs, audit, events and metering. Use rotate_connection_key before expiry and delete_connection to remove stored credentials; revoke upstream credentials separately.
What Fondoo does with beehiiv
Normalized email capabilities:
audiences.list(read): the publications the key can see (GET /publications, first 100), withmemberCount= beehiivstats.active_subscriptions.subscribers.list(read): subscriptions of the connection's publication with beehiiv's cursor pagination (limitis capped at beehiiv's maximum of 100 per call;nextCursoris beehiiv'snext_cursor,nullwhenhas_moreis false). Status mapping:active→subscribed,pending(awaiting double opt-in) →pending,inactive(unsubscribed) →unsubscribed,invalid→cleaned,validating/needs_attention/paused→other. Thestatusfilter mapssubscribed→activeandunsubscribed→inactive.subscribers.upsert_batch(write): for each member, one lookup (GET /subscriptions?email=), then:subscribed, not found: create withreactivate_existing:false,send_welcome_email:false,utm_source:"fondoo", and nodouble_opt_override(the publication's own double opt-in setting applies, so beehiiv itself may send its confirmation email and report the personpending); tags are then added. A create that comes backinactive/invalidis reportedskipped_provider_unsubscribed.subscribed, foundinactiveorinvalid:skipped_provider_unsubscribed, nothing written. Foundneeds_attention/paused:unchanged. Foundactive/pending/validating: tags are added (outcomeupdated) or nothing happens (unchanged). Tags are additive; beehiiv tags are never removed.unsubscribed: found and not alreadyinactive→PUT /subscriptions/by_email/{email}withunsubscribe:true(updated); not found or already inactive →unchanged. Nobody is created or deleted.nameis accepted but not stored (beehiiv subscriptions have no name field; names live in publication-specific custom fields).- One execute makes at most 25 beehiiv requests (up to 3 per member); members beyond that budget come back as
outcome:"error", message:"batch_limit"and must be resent in a later call. 401/403 and 429 abort the whole batch (permission_denied/rate_limited); other per-member failures areerrorrows.
listIdis optional everywhere; when given it must equal the connection'spublicationId, otherwise the call is rejected (connect other publications as separate connections).campaigns.create_draft(write): creates a post withstatus:"draft"(never scheduled or published),body_content= the HTML,email_settings.email_subject_line/email_preview_text/reply_to_address(must be a verified reply-to address in beehiiv, otherwise beehiiv returns 422), andrecipients: { email: { tier_ids: ["all"] } }(email to free and premium tiers, no web target).fromNameis ignored: beehiiv'ssender_nameis a preset key configured in beehiiv, not free text. beehiiv builds posts asynchronously; the returnedcampaignIdis thepost_...ID.campaigns.send(destructive): reads the post first and refuses unless it is adraftwhose platform is not web-only, thenPATCHes it tostatus:"confirmed"(withscheduled_atwhenscheduleAtis given; otherwise beehiiv publishes it now). This is irreversible: beehiiv does not allow moving a confirmed post back to draft. Returnssendingorscheduled.
Vendor-native capabilities: publications.get, subscriptions.get (by email, with tags and custom fields expanded), subscriptions.add_tags (by subscriptionId or email; beehiiv creates missing tags; max 100 unique tags per publication), posts.list, posts.get (default expand[]=stats), segments.list, custom_fields.list, tiers.list (optional prices). All take bounded, validated inputs; page-based lists return page, totalPages, totalResults.
Not implemented: subscription delete (beehiiv: "cannot be undone"; it recommends unsubscribing instead), tag removal, bulk subscription imports, segment/custom-field/tier writes, post delete/update beyond confirming a draft.
API endpoints used
- Publications:
GET /publications,GET /publications/{publicationId}: https://developers.beehiiv.com/api-reference/publications/index and https://developers.beehiiv.com/api-reference/publications/show - Subscriptions:
GET /publications/{id}/subscriptions(cursor pagination,emailfilter): https://developers.beehiiv.com/api-reference/subscriptions/index ;POST /publications/{id}/subscriptions: https://developers.beehiiv.com/api-reference/subscriptions/create ;GET .../subscriptions/by_email/{email}: https://developers.beehiiv.com/api-reference/subscriptions/get-by-email ;PUT .../subscriptions/by_email/{email}: https://developers.beehiiv.com/api-reference/subscriptions/update-by-email - Subscription tags:
POST .../subscriptions/{subscriptionId}/tags: https://developers.beehiiv.com/api-reference/subscription-tags/create - Posts:
POST .../posts: https://developers.beehiiv.com/api-reference/posts/create ;PATCH .../posts/{postId}: https://developers.beehiiv.com/api-reference/posts/update ;GET .../posts: https://developers.beehiiv.com/api-reference/posts/index ;GET .../posts/{postId}: https://developers.beehiiv.com/api-reference/posts/show - Segments:
GET .../segments: https://developers.beehiiv.com/api-reference/segments/index - Custom fields:
GET .../custom_fields: https://developers.beehiiv.com/api-reference/custom-fields/index - Tiers:
GET .../tiers: https://developers.beehiiv.com/api-reference/tiers/index - Rate limits: https://developers.beehiiv.com/welcome/rate-limiting ; API key and publication ID location: https://www.beehiiv.com/support/article/13091918395799-how-to-access-your-publication-id-or-api-keys
Limits and uncertainties
- Rate limit: beehiiv documents per-key limits per 60 s window of 30 (Free), 180 (Lite), 500 (Pro), 800 (Enterprise). Fondoo's local budget is 10 executes per minute because one execute may make up to 25 requests; 429 surfaces as
rate_limitedwithRetry-Afterwhen sent. - Uncertain: plan gating of the Send API. The Create Post page says Max and Enterprise; the Update Post page says Pro and Enterprise; the rate-limit page uses Free/Lite/Pro/Enterprise names. A plan without access returns an error that Fondoo reports as
permission_denied(401/403) orprovider_error. - Uncertain: whether
status:"confirmed"withoutscheduled_atsends the email immediately (the docs say the post is published; email delivery followsrecipients). - Uncertain: list-subscriptions
expand[]does not listtags(onlystats,custom_fields,referrals,newsletter_lists) although the Subscription schema mentionsexpand: [tags]; Fondoo does not request it, sosubscribers.listreturns tags only if beehiiv includes them (normally[]). - Uncertain:
custom_fields.listdocumentslimit/pageonly in the response; they are forwarded only when supplied. - Uncertain:
pausedappears in the subscription status enum without a description; it maps tootherand is never modified. - The Create Subscription page does not say what happens when the email already exists; Fondoo always looks the person up first, so create is only called for unknown addresses.
- beehiiv's bulk subscription create returns only an asynchronous import ID with no per-member result, so Fondoo uses single creates (bounded per execute) instead.
Compliance notes
- Fondoo never re-subscribes someone beehiiv reports
inactive(unsubscribed) orinvalid;reactivate_existingis alwaysfalse(beehiiv: "should be used only if the subscriber is knowingly resubscribing"). - Fondoo never overrides the publication's double opt-in (
double_opt_overrideis never sent) and never sends beehiiv's welcome email. - Core only pushes people who completed Fondoo's own double opt-in. Sending a campaign is destructive and needs owner approval for agents. beehiiv adds its own unsubscribe handling and footer to posts.
