Eshway Subscriptions API

The Subscriptions API from Eshway — 10 operation(s) for subscriptions.

GitHub OpenAPI

Operations 10

GET /v1/subscriptions/plans Get Plans #
GET /v1/subscriptions/my-subscriptions Get My Subscription #
GET /v1/subscriptions/{orgId}/my-subscription Get Org Subscription #
POST /v1/subscriptions/{orgId}/subscribe Create Subscription #
POST /v1/subscriptions/cancel Cancel Subscription #
POST /v1/subscriptions/{orgId}/verify-payment Verify Payment #
POST /v1/subscriptions/{orgId}/upgrade-seat Upgradeseat #
POST /v1/subscriptions/{orgId}/verify-seat-upgrade-payment Verify Seat Upgrade #
POST /v1/subscriptions/debug-payment Debug Payment #
GET /v1/subscriptions/test-razorpay-config Test Razorpay Config #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/eshway-com:eshway-com-subscriptions-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

eshway-com-subscriptions-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Fast Subscriptions API
  version: 0.1.0
tags:
- name: Subscriptions
paths:
  /v1/subscriptions/plans:
    get:
      tags:
      - Subscriptions
      summary: Get Plans
      operationId: get_plans_v1_subscriptions_plans_get
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/SubscriptionPlanSchema'
                type: array
                title: Response Get Plans V1 Subscriptions Plans Get
  /v1/subscriptions/my-subscriptions:
    get:
      tags:
      - Subscriptions
      summary: Get My Subscription
      description: 'The current subscription of every org the caller actively belongs to.


        Org-scoped, not purchase-scoped. This used to filter on

        ``admin_id == current_user.id`` — "subscriptions I personally bought" —

        which showed an org admin "No active subscription found" whenever a

        different admin had done the purchasing (2026-08-17, Adzzat). Any

        active member can already read the same billing fields for their org

        via GET /{orgId}/my-subscription, so listing them here exposes

        nothing new. Mutating endpoints keep their own admin guards.


        Membership is decided by is_still_member (a Python property over the

        membership_periods JSON), so filter in Python, not SQL. Each org''s

        row comes from _get_latest_org_subscription — the same resolver the

        entitlement policy uses — so the plan this page shows and the plan

        the backend enforces cannot disagree; it also owns the

        PENDING-checkout exclusion.'
      operationId: get_my_subscription_v1_subscriptions_my_subscriptions_get
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/OrgSubscriptionSchema'
                type: array
                title: Response Get My Subscription V1 Subscriptions My Subscriptions Get
      security:
      - OAuth2PasswordBearer: []
  /v1/subscriptions/{orgId}/my-subscription:
    get:
      tags:
      - Subscriptions
      summary: Get Org Subscription
      description: 'Read the current subscription for an organization.


        Access: caller must be an active member of orgId. Billing details

        (price, trial_end, members_cap) are organization-scoped — leaving

        this endpoint unauthenticated would let anyone enumerate paying

        customers and their plans by orgId.


        This endpoint no longer performs the trial self-heal write that the

        previous implementation did during a public GET. Performing writes

        on a read path is wrong on multiple axes: it makes the endpoint

        non-cacheable, it can race when the dashboard polls, and (when the

        endpoint was unauthenticated) it let arbitrary callers trigger

        state changes. Self-healing of trial price / trial_end is now

        handled in the dedicated background subscription task — see

        ``app/tasks/subscription_tasks.py``.'
      operationId: get_org_subscription_v1_subscriptions__orgId__my_subscription_get
      security:
      - OAuth2PasswordBearer: []
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: integer
          title: Orgid
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrgSubscriptionSchema'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/subscriptions/{orgId}/subscribe:
    post:
      tags:
      - Subscriptions
      summary: Create Subscription
      operationId: create_subscription_v1_subscriptions__orgId__subscribe_post
      security:
      - OAuth2PasswordBearer: []
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: integer
          title: Orgid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateSubscriptionRequest'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: object
                title: Response Create Subscription V1 Subscriptions  Orgid  Subscribe Post
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/subscriptions/cancel:
    post:
      tags:
      - Subscriptions
      summary: Cancel Subscription
      description: 'Cancel a subscription.


        Authority is checked in two passes:

        1. Locate the subscription by razorpay_subscription_id only —

        we do NOT key on admin_id here, because using a stale

        admin_id row to gate the action lets a former billing

        admin keep cancelling the org''s subscription long after

        they''ve been removed from the org.

        2. Require the caller to be an active org admin of the

        subscription''s CURRENT org.'
      operationId: cancel_subscription_v1_subscriptions_cancel_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CancelSubscriptionRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      security:
      - OAuth2PasswordBearer: []
  /v1/subscriptions/{orgId}/verify-payment:
    post:
      tags:
      - Subscriptions
      summary: Verify Payment
      operationId: verify_payment_v1_subscriptions__orgId__verify_payment_post
      security:
      - OAuth2PasswordBearer: []
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: integer
          title: Orgid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Payment Details
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/subscriptions/{orgId}/upgrade-seat:
    post:
      tags:
      - Subscriptions
      summary: Upgradeseat
      description: 'Create a Razorpay order for a seat upgrade.


        Authority is now bound to active org admin status, not the

        historical admin_id on the subscription row. A removed billing

        admin cannot drive seat upgrades for an org they no longer

        belong to. The Razorpay order notes also bind back to the

        requested orgId, expected admin id, currency, and amount so

        /verify-seat-upgrade-payment can detect mismatches.'
      operationId: upgradeSeat_v1_subscriptions__orgId__upgrade_seat_post
      security:
      - OAuth2PasswordBearer: []
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: integer
          title: Orgid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpgradeSeatSubscriptionRequest'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/subscriptions/{orgId}/verify-seat-upgrade-payment:
    post:
      tags:
      - Subscriptions
      summary: Verify Seat Upgrade
      operationId: verify_seat_upgrade_v1_subscriptions__orgId__verify_seat_upgrade_payment_post
      security:
      - OAuth2PasswordBearer: []
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: integer
          title: Orgid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Payment Details
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/subscriptions/debug-payment:
    post:
      tags:
      - Subscriptions
      summary: Debug Payment
      description: 'Debug endpoint — platform superadmin only.


        Previously gated only by ``settings.DEBUG``. If a misconfigured staging

        or production env had ``DEBUG=True``, anyone could probe Razorpay

        payment/subscription metadata. Now requires both: superadmin auth at

        all times, plus the explicit DEBUG flag (so it cannot be invoked even

        by a superadmin in a production environment).'
      operationId: debug_payment_v1_subscriptions_debug_payment_post
      requestBody:
        content:
          application/json:
            schema:
              type: object
              title: Payment Details
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      security:
      - OAuth2PasswordBearer: []
  /v1/subscriptions/test-razorpay-config:
    get:
      tags:
      - Subscriptions
      summary: Test Razorpay Config
      description: 'Test endpoint to verify Razorpay configuration.


        Requires platform superadmin AND ``settings.DEBUG``. The previous

        implementation gated only on ``DEBUG``, so a misconfigured

        staging/production deploy with ``DEBUG=True`` would have let any

        unauthenticated caller make outbound Razorpay API calls and

        receive both whether live keys are configured AND raw provider

        error text.'
      operationId: test_razorpay_config_v1_subscriptions_test_razorpay_config_get
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
      security:
      - OAuth2PasswordBearer: []
components:
  schemas:
    PlanFeature:
      properties:
        name:
          type: string
          title: Name
        included:
          type: boolean
          title: Included
        description:
          anyOf:
          - type: string
          - type: 'null'
          title: Description
        value:
          anyOf:
          - type: string
          - type: integer
          - type: 'null'
          title: Value
      type: object
      required:
      - name
      - included
      title: PlanFeature
    OrgSubscriptionSchema:
      properties:
        id:
          type: integer
          title: Id
        plan:
          $ref: '#/components/schemas/SubscriptionPlanSchema'
        org_id:
          type: integer
          title: Org Id
        admin_id:
          type: integer
          title: Admin Id
        razorpay_subscription_id:
          anyOf:
          - type: string
          - type: 'null'
          title: Razorpay Subscription Id
        status:
          type: string
          title: Status
        current_period_start:
          type: string
          format: date-time
          title: Current Period Start
        current_period_end:
          anyOf:
          - type: string
            format: date-time
          - type: 'null'
          title: Current Period End
        grace_period_end:
          anyOf:
          - type: string
            format: date-time
          - type: 'null'
          title: Grace Period End
        trial_end:
          anyOf:
          - type: string
            format: date-time
          - type: 'null'
          title: Trial End
        cancel_at_period_end:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Cancel At Period End
        days_until_expiration:
          anyOf:
          - type: integer
          - type: 'null'
          title: Days Until Expiration
        is_active:
          type: boolean
          title: Is Active
        members_cap:
          type: integer
          title: Members Cap
        monthly_bill:
          type: number
          title: Monthly Bill
        currency:
          type: string
          title: Currency
      type: object
      required:
      - id
      - plan
      - org_id
      - admin_id
      - status
      - current_period_start
      - current_period_end
      - trial_end
      - cancel_at_period_end
      - days_until_expiration
      - is_active
      - members_cap
      - monthly_bill
      - currency
      title: OrgSubscriptionSchema
    UpgradeSeatSubscriptionRequest:
      properties:
        additional_seats:
          type: integer
          title: Additional Seats
      type: object
      required:
      - additional_seats
      title: UpgradeSeatSubscriptionRequest
    CreateSubscriptionRequest:
      properties:
        plan_id:
          type: string
          title: Plan Id
        plan_duration:
          type: integer
          title: Plan Duration
        members_cap:
          type: integer
          title: Members Cap
      type: object
      required:
      - plan_id
      - plan_duration
      - members_cap
      title: CreateSubscriptionRequest
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    SubscriptionPlanSchema:
      properties:
        id:
          type: string
          title: Id
        name:
          type: string
          title: Name
        price:
          type: integer
          title: Price
        interval:
          type: string
          title: Interval
        description:
          anyOf:
          - type: string
          - type: 'null'
          title: Description
        duration:
          type: integer
          title: Duration
        features:
          items:
            $ref: '#/components/schemas/PlanFeature'
          type: array
          title: Features
        popular:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Popular
          default: false
        limitations:
          anyOf:
          - items:
              type: string
            type: array
          - type: 'null'
          title: Limitations
          default: []
      type: object
      required:
      - id
      - name
      - price
      - interval
      - description
      - duration
      - features
      title: SubscriptionPlanSchema
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
            - type: string
            - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
      type: object
      required:
      - loc
      - msg
      - type
      title: ValidationError
    CancelSubscriptionRequest:
      properties:
        subscription_id:
          type: string
          title: Subscription Id
      type: object
      required:
      - subscription_id
      title: CancelSubscriptionRequest
  securitySchemes:
    OAuth2PasswordBearer:
      type: oauth2
      flows:
        password:
          scopes: {}
          tokenUrl: token