Medium REST API

The Medium REST API provides programmatic access to the Medium online publishing platform. Developers can authenticate users via OAuth2, retrieve user profile details, list publications a user is associated with, create posts on a user's profile or within a publication, and upload images. The API is JSON-based with all requests made over HTTPS to endpoints under api.medium.com/v1, enabling integrations that automate content publishing workflows on Medium.

OpenAPI Specification

medium-rest-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Medium REST API
  description: >-
    The Medium REST API provides programmatic access to the Medium online
    publishing platform. Developers can authenticate users via self-issued
    access tokens or OAuth2, retrieve user profile details, list publications
    a user is associated with, fetch publication contributors, create posts
    on a user's profile or within a publication, and upload images. The API
    is JSON-based with all requests made over HTTPS to endpoints under
    api.medium.com/v1, enabling integrations that automate content
    publishing workflows on Medium. All responses are wrapped in a data
    envelope object.
  version: '1.0'
  contact:
    name: Medium Support
    url: https://help.medium.com
  termsOfService: https://policy.medium.com/medium-terms-of-service-9db0094a1e0f
externalDocs:
  description: Medium API Documentation
  url: https://github.com/Medium/medium-api-docs
servers:
  - url: https://api.medium.com/v1
    description: Production Server
tags:
  - name: Images
    description: >-
      Operations for uploading images to Medium for use in posts. Supports
      JPEG, PNG, GIF, and TIFF formats.
  - name: Posts
    description: >-
      Operations for creating new posts on a user's profile or within a
      publication, supporting HTML and Markdown content formats.
  - name: Publications
    description: >-
      Operations for listing publications a user is associated with and
      retrieving contributors for a given publication.
  - name: Users
    description: >-
      Operations for retrieving authenticated user profile information
      including username, name, URL, and avatar image.
security:
  - bearerAuth: []
paths:
  /me:
    get:
      operationId: getAuthenticatedUser
      summary: Get authenticated user
      description: >-
        Returns details of the authenticated user including their unique
        user ID, username, display name, profile URL, and avatar image URL.
        This endpoint is typically used after authentication to obtain the
        user ID required by other endpoints.
      tags:
        - Users
      responses:
        '200':
          description: Successfully retrieved the authenticated user profile.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/User'
        '401':
          description: >-
            The access token is invalid, has been revoked, or was not
            provided.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /users/{userId}/publications:
    get:
      operationId: listUserPublications
      summary: List user publications
      description: >-
        Returns a list of publications that the specified user subscribes
        to, writes for, or edits. The authenticated user can only list
        their own publications; attempting to list another user's
        publications will result in a 403 Forbidden error.
      tags:
        - Publications
      parameters:
        - $ref: '#/components/parameters/userId'
      responses:
        '200':
          description: Successfully retrieved the list of user publications.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Publication'
        '401':
          description: >-
            The access token is invalid, has been revoked, or was not
            provided.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: >-
            The authenticated user does not have permission to list
            publications for the specified user.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /publications/{publicationId}/contributors:
    get:
      operationId: listPublicationContributors
      summary: List publication contributors
      description: >-
        Returns a list of contributors (editors and writers) for the
        specified publication. Each contributor includes their user ID,
        the publication ID, and their role within the publication.
      tags:
        - Publications
      parameters:
        - $ref: '#/components/parameters/publicationId'
      responses:
        '200':
          description: Successfully retrieved the list of publication contributors.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Contributor'
        '401':
          description: >-
            The access token is invalid, has been revoked, or was not
            provided.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /users/{authorId}/posts:
    post:
      operationId: createUserPost
      summary: Create a post on a user's profile
      description: >-
        Creates a new post and publishes it on the authenticated user's
        profile. The post content can be provided in HTML or Markdown
        format. By default posts are published publicly, but can also be
        created as drafts or unlisted. A maximum of three tags can be
        applied to each post.
      tags:
        - Posts
      parameters:
        - $ref: '#/components/parameters/authorId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatePostRequest'
      responses:
        '201':
          description: Successfully created the post.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Post'
        '400':
          description: >-
            The request body is malformed or contains invalid values such
            as too many tags or an unsupported content format.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: >-
            The access token is invalid, has been revoked, or was not
            provided.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: >-
            The authenticated user is not authorized to publish posts for
            the specified author.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /publications/{publicationId}/posts:
    post:
      operationId: createPublicationPost
      summary: Create a post in a publication
      description: >-
        Creates a new post within the specified publication. Editors can
        create posts with any publish status. Writers can only create
        drafts which are then submitted for review. Users who are not
        contributors to the publication cannot create posts. The post
        content can be provided in HTML or Markdown format.
      tags:
        - Posts
      parameters:
        - $ref: '#/components/parameters/publicationId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatePostRequest'
      responses:
        '201':
          description: Successfully created the post in the publication.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Post'
        '400':
          description: >-
            The request body is malformed or contains invalid values such
            as too many tags or an unsupported content format.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: >-
            The access token is invalid, has been revoked, or was not
            provided.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: >-
            The authenticated user is not a contributor to the specified
            publication or does not have the required role.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /images:
    post:
      operationId: uploadImage
      summary: Upload an image
      description: >-
        Uploads an image to Medium for use in posts. The image must be
        sent as multipart form data with the field name "image". Supported
        formats are JPEG, PNG, GIF, and TIFF. Only one image can be
        uploaded per request. Medium also automatically side-loads images
        referenced in img src attributes within post content.
      tags:
        - Images
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - image
              properties:
                image:
                  type: string
                  format: binary
                  description: >-
                    The image file to upload. Supported formats are
                    image/jpeg, image/png, image/gif, and image/tiff.
      responses:
        '201':
          description: Successfully uploaded the image.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Image'
        '401':
          description: >-
            The access token is invalid, has been revoked, or was not
            provided.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Self-issued access token generated from Medium account settings
        or an OAuth2 access token obtained via the authorization flow.
  parameters:
    userId:
      name: userId
      in: path
      required: true
      description: >-
        The unique identifier of the user whose publications are being
        listed.
      schema:
        type: string
    authorId:
      name: authorId
      in: path
      required: true
      description: >-
        The unique identifier of the user on whose profile the post will
        be created. Must match the authenticated user.
      schema:
        type: string
    publicationId:
      name: publicationId
      in: path
      required: true
      description: >-
        The unique identifier of the publication.
      schema:
        type: string
  schemas:
    User:
      type: object
      description: >-
        A Medium user profile containing identifying information and
        profile metadata.
      properties:
        id:
          type: string
          description: >-
            The unique identifier for the user on Medium.
        username:
          type: string
          description: >-
            The user's username on Medium, used in their profile URL.
        name:
          type: string
          description: >-
            The user's display name as shown on their profile.
        url:
          type: string
          format: uri
          description: >-
            The URL to the user's Medium profile page.
        imageUrl:
          type: string
          format: uri
          description: >-
            The URL to the user's avatar image on Medium.
    Publication:
      type: object
      description: >-
        A Medium publication that aggregates posts from multiple
        contributors around a shared topic or brand.
      properties:
        id:
          type: string
          description: >-
            The unique identifier for the publication.
        name:
          type: string
          description: >-
            The name of the publication as displayed on Medium.
        description:
          type: string
          description: >-
            A short description of the publication's focus or mission.
        url:
          type: string
          format: uri
          description: >-
            The URL to the publication's homepage on Medium.
        imageUrl:
          type: string
          format: uri
          description: >-
            The URL to the publication's logo or header image.
    Contributor:
      type: object
      description: >-
        A contributor to a Medium publication with a specific editorial
        role.
      properties:
        publicationId:
          type: string
          description: >-
            The unique identifier of the publication the contributor
            belongs to.
        userId:
          type: string
          description: >-
            The unique identifier of the contributing user.
        role:
          type: string
          enum:
            - editor
            - writer
          description: >-
            The role of the contributor within the publication. Editors
            can manage all content while writers can submit drafts.
    CreatePostRequest:
      type: object
      description: >-
        The request body for creating a new post on Medium.
      required:
        - title
        - contentFormat
        - content
      properties:
        title:
          type: string
          maxLength: 100
          description: >-
            The title of the post, limited to 100 characters.
        contentFormat:
          type: string
          enum:
            - html
            - markdown
          description: >-
            The format of the content field, either HTML or Markdown.
        content:
          type: string
          description: >-
            The body content of the post in the format specified by
            contentFormat. HTML content should use semantic tags.
        tags:
          type: array
          maxItems: 3
          items:
            type: string
            maxLength: 25
          description: >-
            Tags to classify the post, limited to a maximum of three
            tags with each tag up to 25 characters.
        canonicalUrl:
          type: string
          format: uri
          description: >-
            The original URL if this post was first published elsewhere.
            Used to set the canonical link for SEO purposes.
        publishStatus:
          type: string
          enum:
            - public
            - draft
            - unlisted
          default: public
          description: >-
            The publish status of the post. Defaults to public if not
            specified. Writers creating publication posts can only use
            draft.
        license:
          type: string
          enum:
            - all-rights-reserved
            - cc-40-by
            - cc-40-by-sa
            - cc-40-by-nd
            - cc-40-by-nc
            - cc-40-by-nc-nd
            - cc-40-by-nc-sa
            - cc-40-zero
            - public-domain
          default: all-rights-reserved
          description: >-
            The license under which the post is published. Defaults to
            all-rights-reserved.
        notifyFollowers:
          type: boolean
          description: >-
            Whether to notify the author's followers about the new post.
    Post:
      type: object
      description: >-
        A published or draft post on Medium containing the post metadata
        and publishing details.
      properties:
        id:
          type: string
          description: >-
            The unique identifier for the post.
        title:
          type: string
          description: >-
            The title of the post.
        authorId:
          type: string
          description: >-
            The unique identifier of the user who authored the post.
        tags:
          type: array
          items:
            type: string
          description: >-
            The tags applied to the post for classification.
        url:
          type: string
          format: uri
          description: >-
            The URL to the post on Medium.
        canonicalUrl:
          type: string
          format: uri
          description: >-
            The canonical URL of the post if it was originally published
            elsewhere.
        publishStatus:
          type: string
          enum:
            - public
            - draft
            - unlisted
          description: >-
            The current publish status of the post.
        publishedAt:
          type: integer
          format: int64
          description: >-
            The timestamp in milliseconds when the post was published.
        license:
          type: string
          description: >-
            The license identifier under which the post is published.
        licenseUrl:
          type: string
          format: uri
          description: >-
            The URL to the full text of the license.
        publicationId:
          type: string
          description: >-
            The unique identifier of the publication the post belongs to,
            if applicable.
    Image:
      type: object
      description: >-
        An uploaded image on Medium with its URL and content hash.
      properties:
        url:
          type: string
          format: uri
          description: >-
            The URL where the uploaded image is hosted on Medium.
        md5:
          type: string
          description: >-
            The MD5 hash of the uploaded image content for verification.
    Error:
      type: object
      description: >-
        An error response from the Medium API containing error details.
      properties:
        errors:
          type: array
          items:
            type: object
            properties:
              message:
                type: string
                description: >-
                  A human-readable description of the error.
              code:
                type: integer
                description: >-
                  The numeric error code identifying the error type.