How to export Medium posts to Markdown format

Medium is a great blogging platform with an intuitive editor is enjoyable to write with, that’s something that can’t always be said for other blogging software. The publication model enabled by the platform allows writers to easily get content in front of new audiences and quickly grow readerships. But whilst the editor and network are fantastic resources, sometimes it’s useful for writers to have access to content outside of the platform.

Over the past few weeks I’ve built an API named unmediumed that allows writers to access stories in Markdown, a widely compatible plain-text markup language. I’m using unmediumed to cross-post my stories to this blog, hopefully others will find it useful for similar use-cases.

The API is built in Scala to deploy to AWS Lambda. It's also open source, so you can view the source code on Github. If you want to see it in action, try visiting this link for an example. But please allow up to 10 seconds for the first response as it may be rendering from a cold start.


TLDR; append a Medium post URL to to have the story converted to Markdown. Keep reading for more detailed usage instructions.

Request types

The API has a single endpoint which accepts a Medium post URL as its only path argument. As URL encoding isn’t necessary when providing the URL this means that any Medium URL can be appended to to have it converted to Markdown:

If the post has a domain, the protocol and domain name can be automatically assumed. This means that for any post on you can just change the domain name to

Unfortunately for posts not on the domain, like those submitted to a publication such as freeCodeCamp, the protocol and host can’t be determined. Consequently if you’re working with posts on publications you need to append the full URL.

Response types

Only text/markdown content type responses are returned by the API. Successful responses will have a HTTP 200 status code. For errors, one of four status codes will be returned depending on the type of error that occurred. A HTTP 422 response will be returned when an invalid post URL has been provided, a HTTP 502 response when there was an error fetching the post content, and a HTTP 500 response if an error occurs during parsing. If working with the API programmatically you can match on these status codes to determine the outcome.

How it’s built

For general usage it’s not necessary to know how unmediumed is built. But for those interested in how it works technically, the API is built in the Scala programming language. Scala is similar to Kotlin in that it runs on the JVM and allows for the pragmatic blending of functional and object-oriented programming styles. It has a strong type system and large standard library which is well suited to building resilient and concurrent systems. I thoroughly enjoy working with Scala and urge anyone doing backend development to consider it. The API has been designed to be deployed to AWS Lambda, Amazon’s serverless compute service where applications are billed by execution time rather than resources provisioned. Whilst it’s is not suitable for every use-case, it’s a good fit here as we want high availability for inconsistent traffic levels. For deployment the API is compiled into a JAR file that includes all of the application dependencies. As Scala compiles down to JVM bytecode, the lambda is configured to use the Java 8 runtime.

Reporting issues

I hope you find unmediumed useful. Whilst I’ve found that it converts my stories to Markdown successfully, I expect that for some content it will need some adjusting. If you run into any problems when using the API please raise an issue on Github and I’ll take a look. I also welcome contributions and pull requests directly.