Publish to 12 destinations
A connection is a destination, not a permission. Every one of these publishes only after a person has approved the specific draft — connecting your CMS removes the copy-and-paste step, not the review. Each connector uses a credential you create and can revoke yourself, without touching your platform login.
Setup guide: Webflow
Where the credential comes from: Webflow → Site settings → Apps & integrations → API access.
What you will need
- API token: A site token with CMS read and write access
- Site ID: Found in Site settings → General
- Collection ID: The blog collection articles are created in
On approve: Creates a collection item, then publishes that item so it is live without a full site publish.
On unpublish: Archives the item. It stays in the CMS, hidden from the live site.
Writes: name ← the title; slug ← the slug; post-body ← the article HTML (rich text); post-summary ← the meta description.
The four fields on the left have to exist in the collection with those slugs before the first publish. They are the defaults of Webflow’s own blog template, so most collections already have them.
Setup guide: Framer
Where the credential comes from: Framer → Site settings → General → Server API.
What you will need
- API token: A Framer Server API key for the project
- Site ID: The Framer project the collection lives in
- Collection ID: The CMS collection articles are created in
On approve: Creates a collection item with draft mode off, so it is live.
On unpublish: Flips the same item back to draft.
Writes: name ← the title; slug ← the slug; content ← the article HTML; description ← the meta description.
Only collections owned and editable by the project work. Collections synced from an external source are managed by that source.
Setup guide: Notion
Where the credential comes from: notion.so/my-integrations → New integration, then share the database with it.
What you will need
- Integration token: From an internal integration you create
- Database ID: The 32-character id in the database URL
On approve: Creates a page in the database, with the body converted from HTML to Notion blocks: paragraphs, headings and list items.
On unpublish: Archives the page.
Writes: Name ← the title (the database’s title property); Slug ← the slug (a text property).
Creating the integration is not enough: you also have to share the specific database with it from the database’s own menu, or every write returns a permission error.
The database needs a text property called Slug next to its Name title. The write fails if it is missing.
The conversion keeps paragraphs, h1 to h3 and list items as plain text and stops at Notion’s limit of 100 blocks per request, so a long article is truncated and inline links and bold are dropped. Notion is a staging destination, not a publishing one.
Setup guide: Ghost
Where the credential comes from: Ghost admin → Settings → Integrations → Add custom integration.
What you will need
- Ghost URL: Your Ghost site URL including https://
- Admin API key: The id:secret pair from a custom integration, pasted as one string
On approve: Creates a post with status "published" through the Admin API, from HTML, with the meta description set. Live at once.
On unpublish: Sets the post back to draft.
Ghost’s Admin API is not available on their Starter plan. If you are on Starter this connector cannot work, and that is a limit on their side.
The key is used to sign a short-lived token for every request; the key itself is never sent to Ghost.
Setup guide: Magento
Where the credential comes from: Magento admin → System → Integrations.
What you will need
- Base URL: Your Magento install URL including https://
- Admin token: The access token from an integration you activate
- Store code (optional): For multi-store installs. Left empty, the default store is used
On approve: Creates a CMS page (not a blog post: Magento has no blog without an extension) with the slug as its URL key, active, and the meta description set. It is reachable at /{slug} at once.
On unpublish: Deletes the CMS page.
The integration has to be activated after it is created, or the token exists but authorises nothing.
Setup guide: Wix
Where the credential comes from: Wix → Settings → API keys (account level).
What you will need
- API key: An account-level key with Blog permissions
- Account ID: Shown alongside the key when you create it
- Site ID: From the URL of your Wix dashboard
On approve: Creates a draft post through the Blog API with the title and the meta description as excerpt, then publishes it.
On unpublish: Unpublishes the post. It stays in Wix as a draft.
Wix API keys are account-level, so scope the permissions to Blog rather than granting the whole account.
Wix takes its post body as structured rich content rather than HTML, and the HTML-to-rich-content conversion is not finished: today the post is created with its title and excerpt and the body has to be pasted in Wix. The adapter is in the open-source repository if you want to help close that.
Setup guide: HubSpot
Where the credential comes from: HubSpot → Settings → Integrations → Private apps.
What you will need
- Access token: From a private app with blog write scopes
- Blog ID (optional): Which blog to post to. Left empty, the blog of your most recent post is used
On approve: Creates a blog post in state PUBLISHED with the slug and meta description set.
On unpublish: Sets the post to DRAFT.
A private app token is scoped and revocable without affecting your HubSpot login or other integrations.
On a portal with no posts yet there is nothing to read the default blog from, so set the Blog ID explicitly.
Not sure which one your site is? You usually do not have to pick. Adding a domain fetches its homepage once and identifies the platform from public signals — a WordPress install says so in a meta tag, Shopify in a response header — and names the signal it matched. When nothing matches, it says so and shows the full list rather than guessing.
What approving does, per destination
Approving is always the publish. Unpublishing is where platforms differ: some take a post back to draft, some archive it, and two can only delete. Read from each adapter, not from the platform’s brochure.
| Destination | On approve | On unpublish |
|---|---|---|
| WordPress | Creates a post through the REST API with status "publish", so it is live at once. The meta description is stored as the post excerpt and the slug is the one you approved. | Sets the same post back to draft. Nothing is deleted. |
| Shopify | Creates a blog article with published set to true and the approval time as its publish date. The meta description becomes the article summary. | Deletes the article from the blog. Shopify has no draft state to return it to through this endpoint. |
| WooCommerce | Creates a WordPress post with status "publish", live at once, with the meta description as the excerpt. | Sets the post back to draft. |
| Webflow | Creates a collection item, then publishes that item so it is live without a full site publish. | Archives the item. It stays in the CMS, hidden from the live site. |
| Framer | Creates a collection item with draft mode off, so it is live. | Flips the same item back to draft. |
| Notion | Creates a page in the database, with the body converted from HTML to Notion blocks: paragraphs, headings and list items. | Archives the page. |
| Ghost | Creates a post with status "published" through the Admin API, from HTML, with the meta description set. Live at once. | Sets the post back to draft. |
| Webhook | POSTs a JSON body with action "publish" and the article. Any 2xx response counts as published; an id and url in the response are recorded as the published id and URL. | POSTs action "unpublish" with the id your endpoint returned. |
| Magento | Creates a CMS page (not a blog post: Magento has no blog without an extension) with the slug as its URL key, active, and the meta description set. It is reachable at /{slug} at once. | Deletes the CMS page. |
| Wix | Creates a draft post through the Blog API with the title and the meta description as excerpt, then publishes it. | Unpublishes the post. It stays in Wix as a draft. |
| HubSpot | Creates a blog post in state PUBLISHED with the slug and meta description set. | Sets the post to DRAFT. |
| GitHub | Commits one Markdown file to the branch at {content directory}/{slug}.md with YAML front matter (title, description, publishDate, tags, ogImage) and the body converted from HTML. Your host’s build deploys it; a commit is not a deploy, so the article is checked for going live afterwards. | Deletes that file in a second commit. The post disappears on the next build, which is the closest a static site has to unpublishing. |
Common questions
Does connecting a CMS mean AltoRank can publish on its own?
No, and that is the point of the product. A connection is a destination, not a permission to act: the publish path requires a person to approve that specific draft first. Connecting WordPress does not create a robot that posts daily; it removes the copy-and-paste step after you have said yes.
Can I publish as a draft instead of live?
Not as a connector setting: the review happens in AltoRank before anything is sent, so approving is the publish. Every destination goes live on approve. If you want a second pair of eyes on the destination side, connect Notion as a staging database and approve there first, or unpublish afterwards, which returns the post to draft on WordPress, WooCommerce, Ghost, Framer, HubSpot and Wix and archives or deletes it on the others. The table above says which.
How do I know which connector my site needs?
Usually you do not have to. When you add a domain, one fetch of its homepage identifies WordPress, WooCommerce, Shopify, Webflow, Ghost, Framer, Wix, HubSpot, Magento, Squarespace, Next.js, Astro, Hugo or Jekyll from public signals and names the signal it matched, so you can tell "we saw a wp-json link" from a guess. When nothing matches it says so and shows the full picker rather than guessing; a wrong guess would send you hunting for a credential that does not exist.
What if my platform is not listed?
Use the webhook connector. It posts the approved article as JSON to any https:// endpoint you control, optionally signed with a shared secret, so anything that can receive JSON can be a destination. Static sites built with Astro, Hugo, Jekyll or Next are the other common case, and the GitHub connector commits Markdown to your repository for those.
How are my credentials stored?
Encrypted at rest, and only the named secret fields of each connection are encrypted, so the connector type stays readable without a key. Every connector on this list uses a credential you create and can revoke yourself, without changing your platform login. If you would rather not hand credentials to a hosted service at all, self-host: it is the same product and the keys never leave your infrastructure.
Can one workspace publish to more than one destination?
Yes. Connections belong to the workspace, and the publish step offers whichever of them are connected. Agencies typically run a workspace per client with that client's own CMS attached to it.
Be the site the assistant names.
Add a domain and the first draft is written while you watch. Every publish is your decision, a click on the draft or a rule you set and can hold, and you can read the source or self-host it free.
Add a domain, it sets up your workspace