Reelspan publishes articles to one of your Hashnode blogs from Markdown. Hashnode takes text posts only: send them with Post text.
What you can post
| Post | How it appears |
|---|---|
| Text | An article on your blog: a title, a Markdown body, up to 5 tags and an optional canonical URL |
The title is hashnode_title, else the first line of the caption, up to 250 characters. The body is hashnode_description, else description, else the whole caption (its first line included).
The cleanest request sends the article's title as
titleand the Markdown body asdescription. If you sendhashnode_title, the caption becomes that title too, so the body must come fromhashnode_descriptionordescription.
Videos and photos can't be sent: the request is refused with UNSUPPORTED_POST_TYPE. To show an image, link one already online in the Markdown.
Articles are always published; Hashnode has no draft option in Reelspan. The result's url is the article on your blog and post_id its id.
Connect your blog
You need a personal access token. Setup takes about a minute.
- On Hashnode, open Account settings → Developer and click Generate new token.
- In the Reelspan dashboard, open Accounts → Connect account, choose the profile and Hashnode, and paste the token.
- With more than one blog, add the one to post to: its address (
yourblog.hashnode.dev) or its publication id. With one blog, leave it empty.
Reelspan checks the token with Hashnode and finds the blog before saving, encrypted.
With the API
curl -X POST https://api.reelspan.com/v1/accounts/hashnode \
-H "Authorization: Bearer $REELSPAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"profile_username": "my-brand", "token": "...", "blog": "yourblog.hashnode.dev"}'import { Reelspan } from 'reelspan';
const reelspan = new Reelspan();
await reelspan.accounts.connect('my-brand', 'hashnode', {
token: process.env.HASHNODE_TOKEN,
blog: 'yourblog.hashnode.dev',
});import os
from reelspan import Reelspan
reelspan = Reelspan()
reelspan.accounts.connect("my-brand", "hashnode", token=os.environ["HASHNODE_TOKEN"], blog="yourblog.hashnode.dev"){ "success": true, "platform": "hashnode", "account": "yourblog.hashnode.dev", "reconnected": false }| Field | Required | Also accepted (Upload-Post) |
|---|---|---|
token |
Yes | pat |
blog |
With more than one blog. Its address or publication id | publication_id |
Connecting again replaces the Hashnode account on that profile. See Connect with credentials.
Example post
curl -X POST https://api.reelspan.com/v1/posts/text \
-H "Authorization: Bearer $REELSPAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"user": "my-brand",
"platform": ["hashnode"],
"title": "How we cut our build time in half",
"description": "## The problem\n\nOur CI took 14 minutes...\n\n## What we changed\n\n...",
"hashnode_tags": "devops, ci, webdev",
"hashnode_canonical_url": "https://example.com/blog/faster-builds"
}'import { Reelspan } from 'reelspan';
import { readFile } from 'node:fs/promises';
const reelspan = new Reelspan();
const post = await reelspan.posts.text({
user: 'my-brand',
platforms: ['hashnode'],
title: 'How we cut our build time in half',
description: await readFile('faster-builds.md', 'utf8'),
extra: { hashnode_tags: 'devops, ci, webdev', hashnode_canonical_url: 'https://example.com/blog/faster-builds' },
});from pathlib import Path
from reelspan import Reelspan
reelspan = Reelspan()
post = reelspan.posts.text(
"my-brand", ["hashnode"], "How we cut our build time in half",
description=Path("faster-builds.md").read_text(),
extra={"hashnode_tags": "devops, ci, webdev", "hashnode_canonical_url": "https://example.com/blog/faster-builds"},
)Fields
| Field | Meaning |
|---|---|
hashnode_title |
The article's title. Falls back to the caption's first line. |
hashnode_description |
The article's Markdown body. Falls back to description. |
description |
The body, when hashnode_description isn't sent. |
title |
The caption: its first line is the title and the whole of it the body, when the fields above aren't sent. |
hashnode_tags |
Tags, separated by commas. Each is lowercased and keeps only letters, digits and -, and is sent as the tag's slug. The first 5 are used. |
hashnode_canonical_url |
Where the article was first published, sent to Hashnode as the original article URL. |
In the dashboard composer, the Hashnode tab has Tags and Canonical URL.
Limits and behaviour
- Tags: 5 per article; any more are dropped without a warning.
- Title: up to 250 characters; longer is cut.
- No first comment: a
first_commentisn't posted; the result says"first_comment": "unsupported"with a warning.
Common errors
| Code | When | Fix |
|---|---|---|
INVALID_TOKEN |
Connecting: Hashnode didn't accept the token | Generate a new token under Account settings → Developer. |
PUBLICATION_REQUIRED |
Connecting: the account has several blogs and none was named, the one named isn't found, or the account has no blog yet. The message lists your blogs | Send blog with one of the listed addresses. |
UNSUPPORTED_POST_TYPE |
The request is a video or photo post | Send articles with POST /v1/posts/text. |
title_required |
The title came out empty | Send a title (or hashnode_title) with text on its first line. |
reauth_required |
Hashnode says the token is no longer valid | Generate a new token and connect again. |
hashnode_error |
Hashnode refused the article. Retried automatically on 429 and 5xx | Read error for Hashnode's reason. |
MISSING_FIELD |
Connecting without token |
Send it. |
Errors when connecting come back as a 400 with the code in error_code. UNSUPPORTED_POST_TYPE refuses the whole request with a 400. Errors when posting are in that network's result. See Errors.