Ghost Offers API

Manage promotional offers for paid membership tiers, including discounts and trial periods.

OpenAPI Specification

ghost-offers-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Ghost Admin Authors Offers API
  description: The Ghost Admin API provides full read and write access to all content and configuration within a Ghost publication. It enables developers to create, update, and delete posts, pages, tags, members, tiers, newsletters, and offers programmatically. Authentication is handled via JSON Web Tokens generated from an Admin API key, integration tokens, or staff access tokens. The Admin API supports everything the Ghost Admin interface can do and more, making it suitable for building custom publishing workflows, content automation, member management systems, and advanced integrations.
  version: '5.0'
  contact:
    name: Ghost Foundation
    url: https://ghost.org/docs/admin-api/
  termsOfService: https://ghost.org/terms/
servers:
- url: https://{site}.ghost.io/ghost/api/admin
  description: Ghost Pro Hosted Site
  variables:
    site:
      default: your-site
      description: Your Ghost site subdomain
- url: '{protocol}://{domain}/ghost/api/admin'
  description: Self-Hosted Ghost Instance
  variables:
    protocol:
      default: https
      enum:
      - https
      - http
    domain:
      default: localhost:2368
      description: Your Ghost instance domain and port
security:
- adminApiToken: []
tags:
- name: Offers
  description: Manage promotional offers for paid membership tiers, including discounts and trial periods.
paths:
  /offers/:
    get:
      operationId: adminBrowseOffers
      summary: Browse offers
      description: Retrieve a list of all promotional offers configured for the publication.
      tags:
      - Offers
      parameters:
      - $ref: '#/components/parameters/fields'
      - $ref: '#/components/parameters/filter'
      - $ref: '#/components/parameters/limit'
      - $ref: '#/components/parameters/page'
      responses:
        '200':
          description: A list of offers
          content:
            application/json:
              schema:
                type: object
                properties:
                  offers:
                    type: array
                    items:
                      $ref: '#/components/schemas/Offer'
                  meta:
                    $ref: '#/components/schemas/PaginationMeta'
        '401':
          $ref: '#/components/responses/Unauthorized'
    post:
      operationId: adminCreateOffer
      summary: Create an offer
      description: Create a new promotional offer for a paid membership tier, including percentage or fixed amount discounts and trial periods.
      tags:
      - Offers
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - offers
              properties:
                offers:
                  type: array
                  items:
                    $ref: '#/components/schemas/OfferInput'
                  minItems: 1
                  maxItems: 1
      responses:
        '201':
          description: Offer created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  offers:
                    type: array
                    items:
                      $ref: '#/components/schemas/Offer'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          $ref: '#/components/responses/ValidationError'
  /offers/{id}/:
    get:
      operationId: adminReadOffer
      summary: Read an offer by ID
      description: Retrieve a single offer by its unique identifier.
      tags:
      - Offers
      parameters:
      - $ref: '#/components/parameters/resourceId'
      - $ref: '#/components/parameters/fields'
      responses:
        '200':
          description: A single offer
          content:
            application/json:
              schema:
                type: object
                properties:
                  offers:
                    type: array
                    items:
                      $ref: '#/components/schemas/Offer'
                    minItems: 1
                    maxItems: 1
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
    put:
      operationId: adminUpdateOffer
      summary: Update an offer
      description: Update an existing offer by its unique identifier.
      tags:
      - Offers
      parameters:
      - $ref: '#/components/parameters/resourceId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - offers
              properties:
                offers:
                  type: array
                  items:
                    $ref: '#/components/schemas/OfferInput'
                  minItems: 1
                  maxItems: 1
      responses:
        '200':
          description: Offer updated successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  offers:
                    type: array
                    items:
                      $ref: '#/components/schemas/Offer'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/ValidationError'
components:
  parameters:
    fields:
      name: fields
      in: query
      required: false
      description: Comma-separated list of fields to return in the response.
      schema:
        type: string
    page:
      name: page
      in: query
      required: false
      description: Page number for paginated results. Defaults to 1.
      schema:
        type: integer
        minimum: 1
        default: 1
    filter:
      name: filter
      in: query
      required: false
      description: Apply fine-grained filters using Ghost's NQL query language.
      schema:
        type: string
    limit:
      name: limit
      in: query
      required: false
      description: Maximum number of resources to return per page. Defaults to 15.
      schema:
        oneOf:
        - type: integer
          minimum: 1
        - type: string
          enum:
          - all
        default: 15
    resourceId:
      name: id
      in: path
      required: true
      description: The unique identifier of the resource
      schema:
        type: string
        format: uuid
  responses:
    Unauthorized:
      description: Authentication failed or token is missing or invalid
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    NotFound:
      description: The requested resource was not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    ValidationError:
      description: Request body validation failed
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  schemas:
    PaginationMeta:
      type: object
      description: Pagination metadata
      properties:
        pagination:
          type: object
          properties:
            page:
              type: integer
              description: Current page
              minimum: 1
            limit:
              type: integer
              description: Items per page
              minimum: 1
            pages:
              type: integer
              description: Total pages
              minimum: 1
            total:
              type: integer
              description: Total items
              minimum: 0
            next:
              type: integer
              description: Next page number
              nullable: true
            prev:
              type: integer
              description: Previous page number
              nullable: true
    Offer:
      type: object
      description: A promotional offer for a paid membership tier.
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier
        name:
          type: string
          description: Internal name for the offer
        code:
          type: string
          description: URL-safe code used in the offer link
        display_title:
          type: string
          description: Public-facing title shown to visitors
        display_description:
          type: string
          description: Public-facing description
          nullable: true
        type:
          type: string
          description: Discount type
          enum:
          - percent
          - fixed
          - trial
        cadence:
          type: string
          description: Which billing cadence the offer applies to
          enum:
          - month
          - year
        amount:
          type: integer
          description: Discount amount. For percent type this is a percentage (1-100). For fixed type this is in the smallest currency unit. For trial type this is the number of days.
          minimum: 0
        duration:
          type: string
          description: How long the discount applies
          enum:
          - once
          - repeating
          - forever
          - trial
        duration_in_months:
          type: integer
          description: Number of months for repeating duration
          nullable: true
          minimum: 1
        currency_restriction:
          type: boolean
          description: Whether the offer has a currency restriction
        currency:
          type: string
          description: Currency for the offer
          nullable: true
          pattern: ^[A-Z]{3}$
        status:
          type: string
          description: Offer status
          enum:
          - active
          - archived
        redemption_count:
          type: integer
          description: Number of times the offer has been redeemed
          minimum: 0
        tier:
          $ref: '#/components/schemas/Tier'
        created_at:
          type: string
          format: date-time
          description: Creation timestamp
        updated_at:
          type: string
          format: date-time
          description: Last update timestamp
    OfferInput:
      type: object
      description: Input fields for creating or updating an offer.
      required:
      - name
      - code
      - display_title
      - type
      - cadence
      - amount
      - duration
      - tier
      properties:
        name:
          type: string
          description: Internal name
        code:
          type: string
          description: URL-safe code
        display_title:
          type: string
          description: Public-facing title
        display_description:
          type: string
          description: Public-facing description
          nullable: true
        type:
          type: string
          enum:
          - percent
          - fixed
          - trial
          description: Discount type
        cadence:
          type: string
          enum:
          - month
          - year
          description: Billing cadence
        amount:
          type: integer
          description: Discount amount
          minimum: 0
        duration:
          type: string
          enum:
          - once
          - repeating
          - forever
          - trial
          description: Discount duration
        duration_in_months:
          type: integer
          description: Months for repeating duration
          nullable: true
          minimum: 1
        currency:
          type: string
          description: Currency code for fixed discounts
          nullable: true
          pattern: ^[A-Z]{3}$
        status:
          type: string
          enum:
          - active
          - archived
          description: Offer status
        tier:
          type: object
          description: Tier to apply the offer to
          required:
          - id
          properties:
            id:
              type: string
              format: uuid
              description: Tier identifier
    ErrorResponse:
      type: object
      description: Standard Ghost API error response
      properties:
        errors:
          type: array
          items:
            type: object
            properties:
              message:
                type: string
                description: Human-readable error message
              type:
                type: string
                description: Error type identifier
              context:
                type: string
                description: Additional error context
                nullable: true
    Tier:
      type: object
      description: A membership tier with pricing and benefits configuration.
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier
        name:
          type: string
          description: Tier name
        slug:
          type: string
          description: URL-safe slug
        description:
          type: string
          description: Tier description
          nullable: true
        active:
          type: boolean
          description: Whether the tier is active
        type:
          type: string
          description: Tier type
          enum:
          - free
          - paid
        welcome_page_url:
          type: string
          format: uri
          description: Welcome page URL after signup
          nullable: true
        visibility:
          type: string
          description: Public visibility
          enum:
          - public
          - none
        monthly_price:
          type: integer
          description: Monthly price in smallest currency unit
          nullable: true
          minimum: 0
        yearly_price:
          type: integer
          description: Yearly price in smallest currency unit
          nullable: true
          minimum: 0
        currency:
          type: string
          description: ISO 4217 currency code
          nullable: true
          pattern: ^[A-Z]{3}$
        trial_days:
          type: integer
          description: Number of free trial days
          minimum: 0
        benefits:
          type: array
          description: Tier benefits
          items:
            type: string
        created_at:
          type: string
          format: date-time
          description: Creation timestamp
        updated_at:
          type: string
          format: date-time
          description: Last update timestamp
  securitySchemes:
    adminApiToken:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JSON Web Token generated from an Admin API key. The key is split into an ID and secret at the colon separator. The ID is used as the kid header and the secret is used to sign the token with HS256.
externalDocs:
  description: Ghost Admin API Documentation
  url: https://ghost.org/docs/admin-api/