info:
  title: Developer API
  version: 2.0.0
security:
  - BearerAuth: []
servers:
  - url: https://api.revenuecat.com/v2
openapi: 3.0.3
tags:
  - name: Paywall
    description: >-
      Part of the [REST API v2 Reference](/docs/api-v2). More Paywall endpoints:
      [Paywall](/docs/api-v2/paywall), [Paywall
      Publishing](/docs/api-v2/paywall/publishing).


      Operations about paywalls.


      #### Endpoints


      - [Get a list of fonts](#tag/Paywall/operation/list-fonts) — `GET
      /projects/{project_id}/fonts`

      - [Upload a font](#tag/Paywall/operation/create-font) — `POST
      /projects/{project_id}/fonts`

      - [Get a list of media assets](#tag/Paywall/operation/list-media-assets) —
      `GET /projects/{project_id}/media_assets`

      - [Upload a media asset](#tag/Paywall/operation/create-media-asset) —
      `POST /projects/{project_id}/media_assets`
    x-displayName: Paywall Fonts & Media
  - name: Endpoint Reference
    x-traitTag: true
    description: >
      All API v2 resources, one page each. General concepts (authentication,
      pagination, rate limits, error handling) live on the [API v2
      overview](/docs/api-v2).


      - [App](/docs/api-v2/app) — 7 endpoints

      - [Audience](/docs/api-v2/audience) — 6 endpoints

      - [Audit Log](/docs/api-v2/audit-log) — 1 endpoint

      - [Charts & Metrics](/docs/api-v2/charts-and-metrics) — 4 endpoints

      - [Collaborator](/docs/api-v2/collaborator) — 1 endpoint

      - [Customer](/docs/api-v2/customer) — 12 endpoints

      - [Customer Resources](/docs/api-v2/customer/resources) — 8 endpoints

      - [Entitlement](/docs/api-v2/entitlement) — 10 endpoints

      - [Integration](/docs/api-v2/integration) — 5 endpoints

      - [Invoice](/docs/api-v2/invoice) — 2 endpoints

      - [Offering](/docs/api-v2/offering) — 7 endpoints

      - [Package](/docs/api-v2/package) — 8 endpoints

      - [Paywall](/docs/api-v2/paywall) — 5 endpoints

      - [Paywall Fonts & Media](/docs/api-v2/paywall/assets) — 4 endpoints

      - [Paywall Publishing](/docs/api-v2/paywall/publishing) — 7 endpoints

      - [Product](/docs/api-v2/product) — 8 endpoints

      - [Project](/docs/api-v2/project) — 2 endpoints

      - [Purchase](/docs/api-v2/purchase) — 4 endpoints

      - [Subscription](/docs/api-v2/subscription) — 9 endpoints

      - [Subscription Data Model](/docs/api-v2/subscription-data-model) — full
      schema reference

      - [Virtual Currency](/docs/api-v2/virtual-currency) — 7 endpoints
paths:
  /projects/{project_id}/fonts:
    get:
      summary: Get a list of fonts
      operationId: list-fonts
      x-revenuecat-rate-limiting-domain: project_configuration
      x-scopes:
        - project_configuration:offerings:read
      x-release-status: public
      tags:
        - Paywall
      parameters:
        - name: project_id
          description: ID of the project
          required: true
          in: path
          schema:
            type: string
            maxLength: 255
            example: proj1ab2c3d4
        - name: starting_after
          in: query
          required: false
          description: >-
            Pagination cursor. Pass the id of the last item from the previous
            page to fetch the next page; omit for the first page.
          schema:
            type: string
            example: ent12354
        - name: limit
          in: query
          required: false
          description: >-
            Maximum number of items to return per page. Values below 1 or above
            100 are clamped to that range rather than rejected.
          schema:
            type: integer
            example: 10
            default: 20
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListFonts'
          headers:
            RevenueCat-Rate-Limit-Current-Usage:
              $ref: '#/components/headers/RateLimitCurrentUsage'
            RevenueCat-Rate-Limit-Current-Limit:
              $ref: '#/components/headers/RateLimitCurrentLimit'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '423':
          $ref: '#/components/responses/Locked'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/InternalError'
      description: >-
        This endpoint requires the following permission(s):
        <code>project_configuration:offerings:read</code>. This endpoint belongs
        to the <strong>Project Configuration</strong> domain, which has a
        default rate limit of <strong>60 requests per minute</strong>.
    post:
      summary: Upload a font
      operationId: create-font
      x-revenuecat-rate-limiting-domain: project_configuration
      x-scopes:
        - project_configuration:offerings:read_write
      x-release-status: public
      tags:
        - Paywall
      parameters:
        - name: project_id
          description: ID of the project
          required: true
          in: path
          schema:
            type: string
            maxLength: 255
            example: proj1ab2c3d4
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - filename
                - content_type
                - file_data_base64
              properties:
                filename:
                  description: >-
                    File name for the uploaded font. Must have a .ttf or .otf
                    extension.
                  type: string
                  minLength: 1
                  maxLength: 255
                  example: GoodSans-Bold.ttf
                content_type:
                  description: MIME type for the uploaded font.
                  type: string
                  enum:
                    - font/ttf
                    - font/otf
                  example: font/ttf
                file_data_base64:
                  description: Base64-encoded font bytes.
                  type: string
                  minLength: 1
                  maxLength: 6990508
                  example: AAEAAAALAIAAAwAwT1MvMg8SBfAAAAC8AAAAYGNtYXAaVsyKAAABHA
      responses:
        '201':
          description: Success. The font was uploaded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Font'
          headers:
            RevenueCat-Rate-Limit-Current-Usage:
              $ref: '#/components/headers/RateLimitCurrentUsage'
            RevenueCat-Rate-Limit-Current-Limit:
              $ref: '#/components/headers/RateLimitCurrentLimit'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '423':
          $ref: '#/components/responses/Locked'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/InternalError'
      description: >-
        This endpoint requires the following permission(s):
        <code>project_configuration:offerings:read_write</code>. This endpoint
        belongs to the <strong>Project Configuration</strong> domain, which has
        a default rate limit of <strong>60 requests per minute</strong>.
  /projects/{project_id}/media_assets:
    get:
      summary: Get a list of media assets
      operationId: list-media-assets
      x-revenuecat-rate-limiting-domain: project_configuration
      x-scopes:
        - project_configuration:offerings:read
      x-release-status: public
      tags:
        - Paywall
      parameters:
        - name: project_id
          description: ID of the project
          required: true
          in: path
          schema:
            type: string
            maxLength: 255
            example: proj1ab2c3d4
        - name: starting_after
          in: query
          required: false
          description: >-
            Pagination cursor. Pass the id of the last item from the previous
            page to fetch the next page; omit for the first page.
          schema:
            type: string
            example: ent12354
        - name: limit
          in: query
          required: false
          description: >-
            Maximum number of items to return per page. Values below 1 or above
            100 are clamped to that range rather than rejected.
          schema:
            type: integer
            example: 10
            default: 20
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListMediaAssets'
          headers:
            RevenueCat-Rate-Limit-Current-Usage:
              $ref: '#/components/headers/RateLimitCurrentUsage'
            RevenueCat-Rate-Limit-Current-Limit:
              $ref: '#/components/headers/RateLimitCurrentLimit'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '423':
          $ref: '#/components/responses/Locked'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/InternalError'
      description: >-
        This endpoint requires the following permission(s):
        <code>project_configuration:offerings:read</code>. This endpoint belongs
        to the <strong>Project Configuration</strong> domain, which has a
        default rate limit of <strong>60 requests per minute</strong>.
    post:
      summary: Upload a media asset
      operationId: create-media-asset
      x-revenuecat-rate-limiting-domain: project_configuration
      x-scopes:
        - project_configuration:offerings:read_write
      x-release-status: public
      tags:
        - Paywall
      parameters:
        - name: project_id
          description: ID of the project
          required: true
          in: path
          schema:
            type: string
            maxLength: 255
            example: proj1ab2c3d4
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - filename
                - content_type
                - file_data_base64
              properties:
                filename:
                  description: File name for the uploaded image.
                  type: string
                  minLength: 1
                  maxLength: 255
                  example: hero.webp
                content_type:
                  description: MIME type for the uploaded image.
                  type: string
                  enum:
                    - image/jpeg
                    - image/png
                    - image/avif
                    - image/heic
                    - image/heif
                    - image/webp
                  example: image/webp
                file_data_base64:
                  description: Base64-encoded image bytes.
                  type: string
                  minLength: 1
                  maxLength: 2796204
                  example: UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA
      responses:
        '201':
          description: Success. The media asset was uploaded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MediaAsset'
          headers:
            RevenueCat-Rate-Limit-Current-Usage:
              $ref: '#/components/headers/RateLimitCurrentUsage'
            RevenueCat-Rate-Limit-Current-Limit:
              $ref: '#/components/headers/RateLimitCurrentLimit'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '423':
          $ref: '#/components/responses/Locked'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/InternalError'
      description: >-
        This endpoint requires the following permission(s):
        <code>project_configuration:offerings:read_write</code>. This endpoint
        belongs to the <strong>Project Configuration</strong> domain, which has
        a default rate limit of <strong>60 requests per minute</strong>.
components:
  schemas:
    ListFonts:
      type: object
      required:
        - items
        - next_page
        - object
        - url
      title: FontList
      properties:
        object:
          description: >-
            String representing the object's type. Objects of the same type
            share the same value. Always has the value `list`.
          enum:
            - list
          type: string
        items:
          description: Details about each object.
          items:
            $ref: '#/components/schemas/Font'
          type: array
        next_page:
          description: >-
            URL to access the next page of the project's fonts. If not present /
            null, there is no next page
          type: string
          nullable: true
          example: /v2/projects/proj1ab2c3d4/fonts?starting_after=font123456789abcdef
        url:
          description: The URL where this list can be accessed.
          maxLength: 5000
          type: string
          example: /v2/projects/proj1ab2c3d4/fonts
      additionalProperties: false
    Font:
      type: object
      required:
        - object
        - id
        - name
        - family_name
        - style
        - weight
        - url
        - font_key
      properties:
        object:
          description: >-
            String representing the object's type. Objects of the same type
            share the same value.
          enum:
            - font
          type: string
          example: font
        id:
          description: The ID of the font.
          type: string
          minLength: 1
          maxLength: 255
          example: font123456789abcdef
        name:
          description: The PostScript name of the font.
          type: string
          minLength: 1
          maxLength: 255
          example: GoodSans-Bold
        family_name:
          description: The font family name.
          type: string
          minLength: 1
          maxLength: 255
          example: Good Sans
        style:
          description: The font style.
          type: string
          enum:
            - normal
            - italic
          example: normal
        weight:
          description: The font weight.
          type: integer
          example: 700
        url:
          description: The URL where the font file is hosted.
          type: string
          minLength: 1
          maxLength: 5000
          example: https://fonts.revenuecat.com/1_abc123_def456.ttf
        font_key:
          description: The key that identifies this font in a paywall's components config.
          type: string
          minLength: 1
          maxLength: 1000
          example: RCFM:1_font123456789abcdef:GoodSans-Bold
      additionalProperties: false
    ListMediaAssets:
      type: object
      required:
        - items
        - next_page
        - object
        - url
      title: MediaAssetList
      properties:
        object:
          description: >-
            String representing the object's type. Objects of the same type
            share the same value. Always has the value `list`.
          enum:
            - list
          type: string
        items:
          description: Details about each object.
          items:
            $ref: '#/components/schemas/MediaAsset'
          type: array
        next_page:
          description: >-
            URL to access the next page of the project's media assets. If not
            present / null, there is no next page
          type: string
          nullable: true
          example: >-
            /v2/projects/proj1ab2c3d4/media_assets?starting_after=mediaasset123456789abcdef
        url:
          description: The URL where this list can be accessed.
          maxLength: 5000
          type: string
          example: /v2/projects/proj1ab2c3d4/media_assets
      additionalProperties: false
    MediaAsset:
      type: object
      required:
        - object
        - id
        - object_name
        - original_name
        - original_size
        - original_width
        - original_height
        - formats
        - alt_text
        - is_decorative
        - asset_base_url
        - asset_type
        - video_metadata
        - transcoding_status
      properties:
        object:
          description: >-
            String representing the object's type. Objects of the same type
            share the same value.
          enum:
            - media_asset
          type: string
          example: media_asset
        id:
          description: The ID of the media asset.
          type: string
          minLength: 1
          maxLength: 255
          example: mediaasset123456789abcdef
        object_name:
          description: The storage object name for the original asset.
          type: string
          minLength: 1
          maxLength: 5000
          example: paywalls/originals/abc123.webp
        original_name:
          description: The uploaded file name.
          type: string
          minLength: 1
          maxLength: 5000
          example: hero.webp
        original_size:
          description: The original file size in kilobytes.
          type: integer
          format: int64
          example: 12345
        original_width:
          description: The original image width in pixels.
          type: integer
          nullable: true
          example: 1024
        original_height:
          description: The original image height in pixels.
          type: integer
          nullable: true
          example: 1024
        formats:
          description: Rendered image formats keyed by format name.
          type: object
          nullable: true
          additionalProperties:
            $ref: '#/components/schemas/MediaAssetFormat'
        alt_text:
          description: Alt text for the asset.
          type: string
          nullable: true
          maxLength: 1500
          example: A dog looking at a phone
        is_decorative:
          description: Whether this asset is decorative.
          type: boolean
          example: false
        asset_base_url:
          description: The base URL where asset object names can be resolved.
          type: string
          nullable: true
          maxLength: 5000
          example: https://paywalls-assets.revenuecat.com
        asset_type:
          description: The media asset type.
          type: string
          enum:
            - image
            - video
          example: image
        video_metadata:
          description: Video metadata, if this is a video asset.
          type: object
          nullable: true
          additionalProperties: true
        transcoding_status:
          description: The video transcoding status, if this is a video asset.
          type: string
          nullable: true
          example: null
      additionalProperties: false
    Error:
      type: object
      required:
        - type
        - message
        - retryable
        - object
      properties:
        object:
          description: >-
            String representing the object's type. Objects of the same type
            share the same value.
          enum:
            - error
          type: string
          example: error
        type:
          description: The error type
          type: string
          nullable: false
          enum:
            - parameter_error
            - resource_already_exists
            - resource_missing
            - idempotency_error
            - rate_limit_error
            - authentication_error
            - authorization_error
            - store_error
            - server_error
            - resource_locked_error
            - unprocessable_entity_error
            - invalid_request
            - entity_references_archived_entities
          example: parameter_error
        param:
          description: >-
            If the error is parameter-specific, the parameter related to the
            error
          type: string
          nullable: true
          example: customer_id
        doc_url:
          description: A URL to more information about the error reported
          type: string
          nullable: false
          example: https://errors.rev.cat/parameter-error
        message:
          type: string
          description: A message describing the reason of the error
          nullable: false
          example: id shouldn't be longer than 1,500 characters
        retryable:
          description: Indicates if the error is retryable or not
          type: boolean
          nullable: false
          example: false
        backoff_ms:
          description: >-
            The ms the client should wait before retrying the request. Only
            present for retryable errors.
          type: integer
          nullable: true
          example: null
        referenced_object_ids:
          description: >-
            The IDs of related objects relevant to the error, such as the
            archived entities that need to be made active before the operation
            can succeed.
          type: array
          items:
            type: string
          example:
            - prodabcd1234
            - prodwxyz5678
      additionalProperties: false
    MediaAssetFormat:
      type: object
      required:
        - object
        - object_name
        - size
        - width
        - height
      properties:
        object:
          description: >-
            String representing the object's type. Objects of the same type
            share the same value.
          enum:
            - media_asset_format
          type: string
          example: media_asset_format
        object_name:
          description: The storage object name for this rendered asset format.
          type: string
          minLength: 1
          maxLength: 5000
          example: paywalls/abc123.webp
        size:
          description: The file size in kilobytes.
          type: integer
          format: int64
          example: 12345
        width:
          description: The image width in pixels.
          type: integer
          nullable: true
          example: 1024
        height:
          description: The image height in pixels.
          type: integer
          nullable: true
          example: 1024
      additionalProperties: false
  headers:
    RateLimitCurrentUsage:
      required: true
      description: >-
        The current number of requests used for the current limit (including the
        current request).
      schema:
        type: integer
      example: 25
    RateLimitCurrentLimit:
      required: true
      description: The rate limit for this endpoint, expressed in requests per minute.
      schema:
        type: integer
      example: 30
    RateLimitRetryAfter:
      required: true
      description: >-
        The number of seconds to wait before retrying a rate limited
        request.Only present when a request is rate limited.
      schema:
        type: integer
      example: 10
  responses:
    BadRequest:
      description: Bad request
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Error'
              - type: object
                properties:
                  type:
                    type: string
                    enum:
                      - parameter_error
                      - invalid_request
          examples:
            parameter_error:
              value:
                object: error
                type: parameter_error
                param: customer_id
                message: id is too long
                retryable: false
                doc_url: https://errors.rev.cat/parameter-error
            invalid_request:
              value:
                object: error
                type: invalid_request
                message: Content-Type not application/json
                retryable: false
                doc_url: https://errors.rev.cat/invalid-request
    Unauthorized:
      description: Unauthorized
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Error'
              - type: object
                properties:
                  type:
                    type: string
                    enum:
                      - authentication_error
            example:
              object: error
              type: authentication_error
              message: Invalid API key
              retryable: false
              doc_url: https://errors.rev.cat/authentication-error
    Forbidden:
      description: Access denied
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Error'
              - type: object
                properties:
                  type:
                    type: string
                    enum:
                      - authorization_error
            example:
              object: error
              type: authorization_error
              message: You're not authorized to access this resource
              retryable: false
              doc_url: https://errors.rev.cat/authorization-error
    NotFound:
      description: Not found
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Error'
              - type: object
                properties:
                  type:
                    type: string
                    enum:
                      - resource_missing
            example:
              object: error
              type: resource_missing
              message: Resource not found
              retryable: false
              doc_url: https://errors.rev.cat/resource-missing
    Locked:
      description: Locked
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Error'
              - type: object
                properties:
                  type:
                    type: string
                    enum:
                      - resource_locked_error
            example:
              object: error
              type: resource_locked_error
              message: The resource is currently being modified by a concurrent request
              retryable: true
              doc_url: https://errors.rev.cat/resource-locked-error
              backoff_ms: 1000
    RateLimited:
      description: >-
        The request could not be completed because the rate limiting domain for
        this endpoint is currently at its limit for this project.
      headers:
        RevenueCat-Rate-Limit-Current-Usage:
          $ref: '#/components/headers/RateLimitCurrentUsage'
        RevenueCat-Rate-Limit-Current-Limit:
          $ref: '#/components/headers/RateLimitCurrentLimit'
        Retry-After:
          $ref: '#/components/headers/RateLimitRetryAfter'
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Error'
              - type: object
                properties:
                  type:
                    type: string
                    enum:
                      - rate_limit_error
            example:
              object: error
              type: rate_limit_error
              message: Rate limit exceeded
              retryable: true
              doc_url: https://errors.rev.cat/rate-limit-error
              backoff_ms: 1000
    InternalError:
      description: Internal server error
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Error'
              - type: object
                properties:
                  type:
                    type: string
                    enum:
                      - server_error
            example:
              object: error
              type: server_error
              message: There was an internal server error
              retryable: true
              doc_url: https://errors.rev.cat/server-error
              backoff_ms: 1000
    Conflict:
      description: Conflict
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Error'
              - type: object
                properties:
                  type:
                    type: string
                    enum:
                      - resource_already_exists
                      - idempotency_error
                      - invalid_request
          examples:
            resource_already_exists:
              value:
                object: error
                type: resource_already_exists
                message: Name is already taken
                retryable: false
                doc_url: https://errors.rev.cat/resource-already-exists
            idempotency_error:
              value:
                object: error
                type: idempotency_error
                message: Idempotency key already used for a different request
                retryable: false
                doc_url: https://errors.rev.cat/idempotency-error
            invalid_request:
              value:
                object: error
                type: invalid_request
                message: Request conflicts with the current resource state
                retryable: false
                doc_url: https://errors.rev.cat/invalid-request
    UnprocessableEntity:
      description: Unprocessable entity
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Error'
              - type: object
                properties:
                  type:
                    type: string
                    enum:
                      - unprocessable_entity_error
                      - parameter_error
                      - store_error
                      - entity_references_archived_entities
          examples:
            unprocessable_entity:
              value:
                object: error
                type: unprocessable_entity_error
                message: Cannot delete a product that has purchases
                retryable: false
                doc_url: https://errors.rev.cat/unprocessable-entity-error
            parameter_error:
              value:
                object: error
                type: parameter_error
                message: Date must in the future
                retryable: false
                doc_url: https://errors.rev.cat/parameter-error
            store_error:
              value:
                object: error
                type: store_error
                message: There was a problem on the App Store
                retryable: true
                doc_url: https://errors.rev.cat/store-error
                backoff_ms: 1000
            entity_references_archived_entities:
              value:
                object: error
                type: entity_references_archived_entities
                message: >-
                  This offering references inactive products. You will need to
                  make the products active first before making the offering
                  active.
                retryable: false
                doc_url: https://errors.rev.cat/entity-references-archived-entities
                referenced_object_ids:
                  - prodabcd1234
                  - prodwxyz5678
  securitySchemes:
    BearerAuth:
      bearerFormat: auth-scheme
      description: >-
        Bearer HTTP authentication. Allowed headers -- Authorization: Bearer
        <api_key>
      scheme: bearer
      type: http
