Skip to content

dsc post

Operations on individual posts (not whole topics). Complements dsc topic pull/push/sync, which only work on the OP.

dsc post pull

dsc post pull <discourse> <post-id> [<local-path>] [--force]

Downloads the raw Markdown body of the specified post. Writes to <local-path> if given, otherwise to stdout. When writing to a file, refuses to overwrite an existing one unless --force is given.

dsc post pull myforum 98765 ./post-98765.md
dsc post pull myforum 98765 > post.md
dsc post pull myforum 98765 ./post-98765.md --force

dsc post push

dsc post push <discourse> <post-id> [<local-path>]

Replaces the body of the specified post with the contents of <local-path> (or stdin if omitted, or -). Requires either an admin API key or a key whose user is the post author. (Alias: dsc post edit.)

dsc post push myforum 98765 ./corrected.md
echo "Edited on the fly." | dsc post push myforum 98765

dsc post delete

dsc post delete <discourse> <post-id>

Soft-deletes the post. This is post-ID based; use it when you know the specific post ID. To delete a whole topic by topic ID, use dsc topic delete. Supports --dry-run (or -n).

dsc post move

dsc post move <discourse> <post-id> --to-topic <topic-id>

Moves the post to a different topic. dsc infers the source topic from the post itself, so you only supply the destination. Prints the URL of the target topic on success. Supports --dry-run.

dsc post move myforum 98765 --to-topic 1525
dsc -n post move myforum 98765 -t 1525   # dry run

dsc post info

dsc post info <discourse> <post-id> [--format text|json|yaml]

Read-only lookup that resolves a post ID to its canonical topic URL and minimal metadata: post ID, topic ID/title/slug/category ID, post number, URL, and deletion state. Supports staff-visible soft-deleted posts and topics. Never prints raw post content, author data, or credentials — use dsc post pull when you need the body. (Alias: dsc post i.)

dsc post info myforum 61695
dsc post info myforum 61695 --format json

dsc post change-owner

dsc post change-owner <discourse> <post-id> <username>

Reassigns the visible author of a single post by ID, without needing its topic ID. Resolves the post's topic the same way dsc post info does, then reassigns just that one post (POST /t/{topic-id}/change-owner.json) - a single-post alias for dsc topic change-owner --post <post-id>. Useful when you have a post ID (e.g. from dsc post info or a Reviewable) but not its topic ID. <username> is validated against the target Discourse before the mutating request is sent. Supports --dry-run.

dsc post change-owner myforum 61695 janedoe
# post 61695 in topic 723 reassigned: opsadmin → janedoe

dsc post revision

dsc post revision list   <discourse> <post-id> [--format text|json|yaml]
dsc post revision show   <discourse> <post-id> <revision> [--format text|json|yaml]
dsc post revision revert <discourse> <post-id> <revision> --yes

Inspect a post's edit history and recover from an accidental overwrite.

  • list follows Discourse's revision links from the latest revision and prints each visible revision newest-first: number, time, editor, changed fields and edit reason (no bodies). Discourse exposes at most the latest 99 revisions, so older history may not be listed. Edits made with --skip-revision leave no revision to recover.
  • show prints one revision's metadata and a raw-Markdown body diff ({+added+}, [-removed-]); JSON/YAML expose the structured API fields.
  • revert asks Discourse to apply the selected revision's prior values (body and, for an opening post, title, category and tags). Staff only; revision numbers below 2 are refused. A live revert requires --yes; --dry-run shows the exact PUT without sending it. After the write, dsc re-fetches the latest revision and fails if no new revision appeared.
dsc post revision list myforum 98765
dsc post revision show myforum 98765 4
dsc -n post revision revert myforum 98765 4
dsc post revision revert myforum 98765 4 --yes

Notes

  • Post edits and deletes require either admin scope or that the API user owns the post.
  • Moving a post that is the first post of its topic will move the whole topic. Discourse's API enforces this.