openapi: 3.1.0
info:
  title: MEGOGO Partner Billing API
  version: 1.0.0
  summary: Users, subscriptions and single purchases for partners that bill their own users.
  description: '`/partners/{partnerId}/...` endpoints only. The Terminals API

    is out of scope.


    ## Access


    The requests are not signed. MEGOGO accepts the requests that read or

    change the services of a user (`subscription/*`, `buyMovie`,

    `user/subscriptions`) only from the IP addresses of the partner. A

    request from another IP address gets HTTP 401. Give your IP

    addresses to your MEGOGO manager. To change the list, send an e-mail to

    supportpartners@megogo.net with your partner ID. A new IP

    address starts to work some minutes after the change.


    ## Limits


    1000 requests per minute for each key. Above this limit, you can get

    HTTP 429 Too Many Requests.


    ## Test environment


    There is no separate test environment. MEGOGO gives each partner a test

    partner ID (for example `testprod_ua`, `testprod_az`) and test keys on

    production.


    ## Billing rule


    MEGOGO records the subscription or the purchase when the request is

    successful (`"successful": true`), even if the user does not watch.

    Start to bill the user only after a successful response.


    ## Retries


    Send the request again only after a timeout or an HTTP 5xx response.

    Wait 1 minute between the attempts. Make a maximum of 6 attempts.

    For `subscribe`, read the WARNING in "Renewal modes" first.


    ## Errors


    An error comes with HTTP 200 and this body:


    ```json

    {"successful": false, "message": "<text>, code <number>"}

    ```


    The message text is not fixed. It can contain the error code. Do not

    parse the text, except to find the code. A request from an IP address

    or a partner ID that MEGOGO does not know gets HTTP 401 with a plain

    text body (not JSON).


    The most frequent error is 2023: the service is already active for this

    user. Other codes help the MEGOGO team to find the cause

    of a problem. Give the code and the time of the request to MEGOGO

    support.


    | Code | Name | Meaning |

    |---|---|---|

    | 2009 | SUBSCRIPTION_NOT_SELLING | The subscription is not for sale |

    | 2010 | SUBSCRIPTION_NOT_FOUND | The subscription is not found |

    | 2012 | INVALID_PERMISSIONS | The settings of the subscription or the tariff are not correct |

    | 2013 | SUBSCRIPTION_NOT_GEO_PRESENTED | The subscription is not available in the region |

    | 2015 | OBJECT_NO_VOD_PERMISSION_FOR_SALE | The video has no delivery rule for sale |

    | 2016 | USER_SERVICE_CREATION_ERROR | MEGOGO cannot create the service of the user |

    | 2017 | USER_SERVICE_NOT_FOUND | The service of the partner is not found |

    | 2022 | TARIFF_ID_DOESNT_MATCH_ORDER_SERVICE_ID | The tariff ID is not the tariff of this service
    |

    | 2023 | PROLONGATION_DISABLED | The service is already active for this user (`subscribe` or `resume`).
    No action is necessary |

    | 2027 | DATE_FINISH_OUT_OF_BOUNDS | The end date is more than 5 years from now. You cannot renew
    more |

    | 2029 | VOD_RULES_NOT_FOUND_FOR_OBJECT | The video has no delivery rules |

    | 2031 | SUBSCRIPTION_QUALITY_FOR_OBJECT_NOT_FOUND | This quality of the video is not in the service
    |

    | 400 | — | The request cannot be done. For example, `buyMovie` for a video that the user already
    bought |

    | 4001 | OBJECT_PREVIOUSLY_PURCHASED | The user already bought this video  |

    | 4003 | PARTNER_NOT_FOUND | The partner is not found |

    | 5001 | USER_NOT_FOUND | The user is not found (`"message": "User not found"`) |

    | 40416 | — | The service ID or the tariff ID is not found for this partner |

    | 42901 | error.too_many_requests | Too many requests. The limit is 1000 requests per minute for each
    key |




    ## Renewal modes


    MEGOGO sets one of two modes for each subscription service:


    | Mode | Renewal | Repeated `subscribe` for an active subscription |

    |---|---|---|

    | Automatic renewal | MEGOGO renews the subscription every period until the partner sends `unsubscribe`
    | Error 2023: the service is already active for this user. No action is necessary |

    | No automatic renewal | The partner renews the subscription: it sends `subscribe` again | Adds one
    period for each request |


    The period is set in the tariff of the service. Usually it is 30 days.

    The test service `ottsvod` of `testprod_ua` has automatic renewal and a

    period of 30 days.

    MEGOGO can give separate services for trial access (for example 7 or 14

    days). Do not calculate the end date: get `dateFinish` from

    `user/subscriptions`.


    WARNING: In the mode without automatic renewal, `subscribe` is **not

    idempotent**. Each successful request adds one more period. Before you

    send the request again after a timeout, get `user/subscriptions` and

    make sure that the first request was not applied.


    WARNING: The end date of a subscription cannot be more than 5 years

    from now. A `subscribe` request that goes past this limit fails with

    error 2027.


    ## Logging


    We recommend that you keep a log of all requests and responses.

    '
servers:
- url: https://billing.megogo.net
  description: 'Production

    '
tags:
- name: Users
- name: Subscriptions
- name: Single purchases
paths:
  /partners/{partnerId}/user/create:
    get:
      tags:
      - Users
      operationId: createUser
      summary: Create a user without a service
      description: 'Creates the user in the MEGOGO billing. Use it when the user must

        sign in (`/auth/by_partners`) before a purchase.

        `subscribe` and `buyMovie` also create the user.


        You can send the request again: it returns the same `uid`.

        '
      parameters:
      - $ref: '#/components/parameters/partnerId'
      - $ref: '#/components/parameters/identifier'
      responses:
        '200':
          description: 'The user is created.

            '
          content:
            application/json:
              schema:
                type: object
                properties:
                  uid:
                    type: integer
                    description: 'The MEGOGO user ID.

                      '
  /partners/{partnerId}/user/innerId:
    get:
      tags:
      - Users
      operationId: getUserInnerId
      summary: Get the MEGOGO user ID and login
      description: 'Also creates the user if the user does not exist.

        '
      parameters:
      - $ref: '#/components/parameters/partnerId'
      - $ref: '#/components/parameters/identifier'
      responses:
        '200':
          description: 'The MEGOGO user ID. The response has only `uid`.

            '
          content:
            application/json:
              schema:
                type: object
                properties:
                  uid:
                    type: integer
  /partners/{partnerId}/user/subscriptions:
    get:
      tags:
      - Users
      operationId: listUserServices
      summary: Get the active services of a user
      description: 'Use this request to make sure that the services of the user are the

        same in your system and in MEGOGO. Also use it before you

        retry `subscribe` or `buyMovie`. The response contains only the

        services that you activated with this API.

        '
      parameters:
      - $ref: '#/components/parameters/partnerId'
      - $ref: '#/components/parameters/identifier'
      responses:
        '200':
          description: 'Active subscriptions and purchased videos.

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserServices'
              example:
                identifier: user123
                svod:
                - serviceId: examplesvod
                  serviceName: SVOD partners
                  dateFinish: 1798649598
                  dateFinishString: '2026-12-30 16:53:18'
  /partners/{partnerId}/subscription/{operation}:
    get:
      tags:
      - Subscriptions
      operationId: changeSubscription
      summary: Subscribe, unsubscribe, suspend or resume
      description: "Changes the subscription of a user. Creates the user if the user does\nnot exist.\n\
        \n- `subscribe` — start the subscription. For an **active**\n  subscription, the result depends\
        \ on the renewal mode of the\n  service: automatic renewal → error 2023 (already active, no action\n\
        \  is necessary); no automatic renewal → one more period. See\n  \"Renewal modes\".\n- `unsubscribe`\
        \ — stop the subscription. Access stops\n  **immediately**: the subscription is not in `user/subscriptions`\n\
        \  after the request. A repeated `unsubscribe` gives\n  `\"successful\": true`. You decide when\
        \ to send the request, for\n  example at the time of the cancellation or at the end of the\n \
        \ period that the user paid.\n- `suspend` — suspend the subscription. The user has no access.\
        \ The\n  subscription is not in `user/subscriptions` until `resume`. The\n  user does not lose\
        \ the paid time: after `resume`, the end date\n  moves forward by the time of the suspension.\
        \ A repeated `suspend`\n  gives `\"successful\": true`.\n- `resume` — resume a suspended subscription.\
        \ For an active\n  subscription: error 2023.\n\nTo change the service, send `unsubscribe` for\
        \ the old service, then\n`subscribe` for the new service.\n"
      parameters:
      - $ref: '#/components/parameters/partnerId'
      - name: operation
        in: path
        required: true
        schema:
          type: string
          enum:
          - subscribe
          - unsubscribe
          - suspend
          - resume
      - $ref: '#/components/parameters/userId'
      - $ref: '#/components/parameters/serviceId'
      responses:
        '200':
          description: 'The result.

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Result'
        '500':
          $ref: '#/components/responses/ServerError'
  /partners/{partnerId}/buyMovie:
    get:
      tags:
      - Single purchases
      operationId: buyMovie
      summary: Record a purchase of a video (TVOD/DTO)
      description: 'Records that the user bought the video. TVOD must be enabled on the

        partner keys.


        `serviceId` is the `tariff_id` that the Content API returns for this

        video in `purchase_info`. Do not use the

        `subscription_id` from the Content API. Do not use the prices and

        the IDs from the XML feed: they are MEGOGO tariffs. A wrong

        `serviceId` gives error 40416.


        The rent period starts when the user starts to watch: at the first

        `/stream` request that returns `src`. Until then, the purchase has

        the status `unwatched` and no end date.


        A repeated `buyMovie` for the same video gives error 400.

        '
      parameters:
      - $ref: '#/components/parameters/partnerId'
      - $ref: '#/components/parameters/userId'
      - name: videoId
        in: query
        required: true
        schema:
          type: integer
      - $ref: '#/components/parameters/serviceId'
      responses:
        '200':
          description: 'The result.

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Result'
        '500':
          $ref: '#/components/responses/ServerError'
components:
  parameters:
    partnerId:
      name: partnerId
      in: path
      required: true
      description: 'The partner ID.

        '
      schema:
        type: string
    identifier:
      name: identifier
      in: query
      required: true
      description: 'The user identifier on the partner side. Any string up to 255

        characters: contract number, account number, login, phone number, or

        a hash if you do not want to send real user data.

        '
      schema:
        type: string
        maxLength: 255
    userId:
      name: userId
      in: query
      required: true
      description: 'The user identifier on the partner side. The same value as `identifier`.

        '
      schema:
        type: string
        maxLength: 255
    serviceId:
      name: serviceId
      in: query
      required: true
      description: 'The service ID. MEGOGO makes it and gives it to the partner.

        '
      schema:
        type: string
  responses:
    ServerError:
      description: 'Temporary error. Before you retry `subscribe` or `buyMovie`, check the

        user services with `user/subscriptions` (the requests are not

        idempotent).

        '
  schemas:
    Result:
      type: object
      properties:
        successful:
          type: boolean
          description: '`true` — the operation is done. Start to bill the user. Any other

            response — do not bill the user. See the error codes in the

            description of this API.

            '
        message:
          type: string
    UserServices:
      type: object
      properties:
        identifier:
          type: string
        svod:
          type: array
          items:
            type: object
            properties:
              serviceId:
                type: string
              serviceName:
                type: string
              dateFinish:
                type: integer
                description: 'Unix time (seconds).

                  '
              dateFinishString:
                type: string
                description: '`YYYY-MM-DD hh:mm:ss`, UTC.

                  '
        tvod:
          type: array
          description: 'Purchased videos. The key is not in the response if the

            user has no purchases. `svod` is always in the response.

            '
          items:
            type: object
            properties:
              serviceId:
                type: string
                description: 'The tariff ID that was sent in `buyMovie`, as a string.

                  '
              serviceName:
                type: string
              objectId:
                type: integer
                description: 'The video ID.

                  '
              status:
                type: string
                enum:
                - unwatched
                - started
                description: '`unwatched` — the rent period did not start. `started` — the user started
                  to watch.

                  '
              dateFinish:
                type: integer
                description: 'The end of the rent period, Unix time (seconds). Only for `started`.

                  '
              dateFinishString:
                type: string
                description: '`YYYY-MM-DD hh:mm:ss`, UTC. Only for `started`.

                  '
