Repository navigation
API Reference
Everything the package exports, as the published 2.0.0 has it. "Since" names the version that added a member; the rest were already in 1.x.
Both builds export the same names. import * as m from 'stack-exchange-markdown-retriever' and require('stack-exchange-markdown-retriever') both list:
[
"StackExchangeError",
"default",
"retrieveMarkdown"
]| Export | Kind | Since |
|---|---|---|
retrieveMarkdown |
function | 1.0.0 |
StackExchangeError |
class | 2.0.0 |
default |
object holding retrieveMarkdown and StackExchangeError
|
2.0.0 |
1.x's require returned an object whose only own key was retrieveMarkdown. 2.0.0's has __esModule, StackExchangeError, default, retrieveMarkdown and Symbol.toStringTag, so code that listed the keys of the module sees more.
| RetrieveMarkdownOptions, RetrieveMarkdownCallback, StackExchangeErrorDetails | TypeScript types | 2.0.0 |
The package's exports map has . (with import and require) and ./package.json, so deep imports such as stack-exchange-markdown-retriever/dist/index.cjs do not resolve. The command line tool is the bin entry, dist/cli.mjs (see Commands).
The ES module build and the CommonJS build are separate copies of the code. A program that loads both gets two different functions and two different StackExchangeError classes:
esm.retrieveMarkdown === esm.default.retrieveMarkdown: true
cjs.retrieveMarkdown === esm.retrieveMarkdown: false
So an error from the CommonJS build fails instanceof against the ES module class; compare error.name === 'StackExchangeError' when both builds may be in play.
function retrieveMarkdown(options: RetrieveMarkdownOptions, callback: RetrieveMarkdownCallback): void;
function retrieveMarkdown(options: RetrieveMarkdownOptions): Promise<string | null>;retrieveMarkdown.length is 2.
| Option | Type | Default | Since | What it does |
|---|---|---|---|---|
entityId |
number | string |
required | 1.0.0 | The post id: a whole number, a string of digits, or such ids joined by ;. Anything else throws a TypeError (since 2.0.0). |
isForAnswer |
boolean |
false |
1.0.0 | Request /answers/<id> instead of /questions/<id>. Any truthy value counts. |
site |
string |
'stackoverflow' |
1.0.0 | The API's site parameter: a short name (scifi) or a domain (scifi.stackexchange.com). An empty string means the default. |
apiKey |
string |
none | 1.0.0 | Sent as the key parameter. An empty string is left out. |
timeout |
number |
30000 |
2.0.0 | Milliseconds before the call fails with a TimeoutError. 0 turns it off. Values above 2147483647 are cut to 2147483647. |
signal |
AbortSignal |
none | 2.0.0 | Aborts the call; it then fails with the signal's reason. |
Other properties are ignored. The exact request each option builds is on How markdown is retrieved.
Returns undefined and calls callback(markdown, error) exactly once, always after retrieveMarkdown has returned:
-
markdownis the post'sbody_markdownas the API sent it,nullwhen there is no such post or on an error, andundefinedwhen the post came back without abody_markdownfield. Abody_markdownthat is not a string (a number, say) is passed on as it is. -
errorisnull, or the error described under Errors.
An exception thrown inside the callback is not caught: it becomes an uncaught exception, and the callback is not called again (1.x called it a second time with that exception).
Returns a Promise that resolves to the markdown string, or null when there is no such post, when the post has no body_markdown, or when body_markdown is not a string. It rejects with the same errors the callback would get. Argument errors reject too; they do not throw.
Passing null as the callback also gives the Promise form:
const result = retrieveMarkdown({entityId: 1}, null);
console.log(result instanceof Promise, await result);prints (sample content):
true Sample question one.
Argument errors come before any request. In the callback form they throw; in the Promise form they reject.
| Cause | Error |
|---|---|
options missing |
TypeError: Cannot read properties of undefined (reading 'entityId') |
entityId missing, 0, '', NaN or false
|
Error: Need an entity id to read |
entityId not a post id |
TypeError: entityId must be a post id (digits, or ids joined by ";"), not "abc" (the value is shown: not -1, not an array, not 1.5) |
callback neither a function nor null/undefined
|
TypeError: callback must be a function, not "callback" |
timeout not a number, NaN or negative |
TypeError: timeout must be a number of milliseconds, 0 or more, not "5000" |
signal not an AbortSignal
|
TypeError: signal must be an AbortSignal |
After the request is sent, the error is one of these:
| What happened | Error |
|---|---|
The API answered with an error_message
|
StackExchangeError with that message, status, errorId, errorName
|
| The body is not the API's JSON (an HTML page, empty, cut off) |
StackExchangeError: The response is not JSON, with the parse error as cause
|
| A body without a Content-Encoding header that decompresses to more than 64 MiB | StackExchangeError: The decompressed response is larger than 67108864 bytes |
| The network failed | the platform's error, on Node TypeError: fetch failed
|
The timeout passed |
TimeoutError: The operation timed out. (a DOMException) |
The signal aborted |
the signal's reason, by default AbortError: This operation was aborted
|
Every message above was printed by the published package; Edge cases and errors has the input behind each one.
class StackExchangeError extends Error {
constructor(message: string, details: StackExchangeErrorDetails);
readonly status: number;
readonly errorId: number | undefined;
readonly errorName: string | undefined;
}name is 'StackExchangeError'. cause is set only when details.cause was given (the parse or decompression error).
From an API error (the stand-in's error body; the real API's message wording can differ):
{
"name": "StackExchangeError",
"message": "ids",
"status": 400,
"errorId": 400,
"errorName": "bad_parameter",
"instanceofStackExchangeError": true,
"instanceofError": true,
"cause": "<undefined>"
}From an HTML error page with status 500:
{
"name": "StackExchangeError",
"message": "The response is not JSON",
"status": 500,
"errorId": "<undefined>",
"errorName": "<undefined>",
"cause": "SyntaxError: Unexpected token '<', \"<html><bod\"... is not valid JSON"
}("<undefined>" is how the verification script prints undefined.)
You can build one yourself, for example in a test double:
const error = new StackExchangeError('Something failed', {status: 503});
console.log(error.name, error.message, error.status, error.errorId);prints:
StackExchangeError Something failed 503 undefined
-
RetrieveMarkdownOptions: the options table above. -
RetrieveMarkdownCallback:(markdown: string | null | undefined, error: Error | null) => void. -
StackExchangeErrorDetails:{status: number; errorId?: number | undefined; errorName?: string | undefined; cause?: unknown}.
This wiki describes stack-exchange-markdown-retriever 2.0.0 and was last updated on 2026-09-29. The library is MIT licensed. Report problems in the issues. On npm: stack-exchange-markdown-retriever.
Using it
The releases
Contributing
Elsewhere