openapi: 3.0.3
info:
  title: hi4.in URL Shortener API
  description: A secure, API-first URL shortener with analytics, payments, and admin features
  version: 1.0.0
  contact:
    name: hi4.in Support
    url: https://zone.radiatus.com/hi4in
    email: support@hi4.in
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT

servers:
  - url: https://zone.radiatus.com/hi4in/api/v1
    description: Production server
  - url: http://localhost/hi4in/api/v1
    description: Development server

security:
  - ApiKeyAuth: []
  - BearerAuth: []

paths:
  /auth/login:
    post:
      summary: Authenticate user
      description: Login with email and password to get JWT token
      tags:
        - Authentication
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - email
                - password
              properties:
                email:
                  type: string
                  format: email
                  example: admin@hi4.in
                password:
                  type: string
                  format: password
                  example: admin123
      responses:
        '200':
          description: Login successful
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: Login successful
                  data:
                    type: object
                    properties:
                      token:
                        type: string
                        example: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
                      expires_in:
                        type: integer
                        example: 3600
                      user:
                        $ref: '#/components/schemas/User'
        '401':
          description: Invalid credentials
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /links:
    get:
      summary: Get user's links
      description: Retrieve paginated list of user's shortened links
      tags:
        - Links
      parameters:
        - name: page
          in: query
          description: Page number
          required: false
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: limit
          in: query
          description: Number of links per page
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
        - name: search
          in: query
          description: Search term for links
          required: false
          schema:
            type: string
      responses:
        '200':
          description: Links retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: object
                    properties:
                      links:
                        type: array
                        items:
                          $ref: '#/components/schemas/Link'
                      pagination:
                        $ref: '#/components/schemas/Pagination'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

    post:
      summary: Create a new link
      description: Shorten a URL and create a new link
      tags:
        - Links
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - long_url
              properties:
                long_url:
                  type: string
                  format: uri
                  example: https://www.google.com
                custom_slug:
                  type: string
                  example: my-custom-link
                title:
                  type: string
                  example: My Awesome Link
                is_public:
                  type: boolean
                  default: true
                password:
                  type: string
                  example: mypassword
                expires_at:
                  type: string
                  format: date-time
                  example: 2024-12-31T23:59:59Z
                domain_id:
                  type: integer
                  example: 1
      responses:
        '200':
          description: Link created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: Link created successfully
                  data:
                    $ref: '#/components/schemas/LinkResponse'
        '400':
          description: Invalid input
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /links/{id}:
    get:
      summary: Get link details
      description: Retrieve details of a specific link
      tags:
        - Links
      parameters:
        - name: id
          in: path
          required: true
          description: Link ID
          schema:
            type: integer
      responses:
        '200':
          description: Link details retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    $ref: '#/components/schemas/Link'
        '404':
          description: Link not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

    put:
      summary: Update link
      description: Update an existing link
      tags:
        - Links
      parameters:
        - name: id
          in: path
          required: true
          description: Link ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                long_url:
                  type: string
                  format: uri
                title:
                  type: string
                is_public:
                  type: boolean
                password:
                  type: string
                expires_at:
                  type: string
                  format: date-time
      responses:
        '200':
          description: Link updated successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: Link updated successfully
        '404':
          description: Link not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

    delete:
      summary: Delete link
      description: Delete a link permanently
      tags:
        - Links
      parameters:
        - name: id
          in: path
          required: true
          description: Link ID
          schema:
            type: integer
      responses:
        '200':
          description: Link deleted successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: Link deleted successfully
        '404':
          description: Link not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /links/{id}/analytics:
    get:
      summary: Get link analytics
      description: Retrieve analytics data for a specific link
      tags:
        - Analytics
      parameters:
        - name: id
          in: path
          required: true
          description: Link ID
          schema:
            type: integer
        - name: days
          in: query
          description: Number of days to analyze
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 365
            default: 30
      responses:
        '200':
          description: Analytics data retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    $ref: '#/components/schemas/Analytics'
        '404':
          description: Link not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /payments/create:
    post:
      summary: Create payment
      description: Create a new payment for credits
      tags:
        - Payments
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - amount
                - provider
              properties:
                amount:
                  type: number
                  minimum: 1
                  maximum: 1000
                  example: 10.00
                provider:
                  type: string
                  enum: [stripe, razorpay]
                  example: stripe
                currency:
                  type: string
                  default: USD
                  example: USD
      responses:
        '200':
          description: Payment created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: Payment created successfully
                  data:
                    $ref: '#/components/schemas/PaymentResponse'
        '400':
          description: Invalid input
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /bulk-links:
    post:
      summary: Bulk create links
      description: Create multiple links from CSV upload
      tags:
        - Links
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                csv_file:
                  type: string
                  format: binary
                  description: CSV file with columns: long_url, custom_slug, title, expires_at
      responses:
        '200':
          description: Bulk operation completed
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    $ref: '#/components/schemas/BulkResponse'
        '400':
          description: Invalid file or data
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /stats:
    get:
      summary: Get statistics
      description: Get user and global statistics
      tags:
        - Statistics
      responses:
        '200':
          description: Statistics retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    $ref: '#/components/schemas/Stats'

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: API key for authentication
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT token for authentication

  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
          example: 1
        email:
          type: string
          format: email
          example: admin@hi4.in
        display_name:
          type: string
          example: Admin User
        role:
          type: string
          enum: [superadmin, admin, analyst, user]
          example: admin
        credits:
          type: number
          format: float
          example: 100.50
        created_at:
          type: string
          format: date-time
          example: 2024-01-01T00:00:00Z

    Link:
      type: object
      properties:
        id:
          type: integer
          example: 1
        slug:
          type: string
          example: abc123
        long_url:
          type: string
          format: uri
          example: https://www.google.com
        title:
          type: string
          example: Google Search
        is_public:
          type: boolean
          example: true
        clicks_count:
          type: integer
          example: 150
        created_at:
          type: string
          format: date-time
          example: 2024-01-01T00:00:00Z
        expires_at:
          type: string
          format: date-time
          nullable: true
          example: 2024-12-31T23:59:59Z
        owner:
          type: string
          example: Admin User

    LinkResponse:
      type: object
      properties:
        id:
          type: integer
          example: 1
        slug:
          type: string
          example: abc123
        short_url:
          type: string
          format: uri
          example: https://hi4.in/r/abc123
        long_url:
          type: string
          format: uri
          example: https://www.google.com
        title:
          type: string
          example: Google Search
        expires_at:
          type: string
          format: date-time
          nullable: true
          example: 2024-12-31T23:59:59Z
        credits_used:
          type: integer
          example: 1

    Analytics:
      type: object
      properties:
        overview:
          type: object
          properties:
            total_clicks:
              type: integer
              example: 150
            unique_clicks:
              type: integer
              example: 120
            countries:
              type: integer
              example: 15
            devices:
              type: integer
              example: 3
            browsers:
              type: integer
              example: 5
        daily_clicks:
          type: array
          items:
            type: object
            properties:
              date:
                type: string
                format: date
                example: 2024-01-01
              clicks:
                type: integer
                example: 25
              unique_clicks:
                type: integer
                example: 20
        top_countries:
          type: array
          items:
            type: object
            properties:
              country:
                type: string
                example: United States
              clicks:
                type: integer
                example: 75
        top_devices:
          type: array
          items:
            type: object
            properties:
              device_type:
                type: string
                example: desktop
              clicks:
                type: integer
                example: 100
        top_browsers:
          type: array
          items:
            type: object
            properties:
              browser:
                type: string
                example: Chrome
              clicks:
                type: integer
                example: 80
        recent_clicks:
          type: array
          items:
            type: object
            properties:
              created_at:
                type: string
                format: date-time
                example: 2024-01-01T12:00:00Z
              ip:
                type: string
                example: 192.168.1.1
              country:
                type: string
                example: United States
              city:
                type: string
                example: New York
              device_type:
                type: string
                example: desktop
              browser:
                type: string
                example: Chrome
              referrer:
                type: string
                example: https://www.google.com
              suspicious:
                type: boolean
                example: false

    PaymentResponse:
      type: object
      properties:
        payment_id:
          type: integer
          example: 1
        amount:
          type: number
          example: 10.00
        currency:
          type: string
          example: USD
        client_secret:
          type: string
          example: pi_test_1234567890
        payment_url:
          type: string
          format: uri
          nullable: true
          example: https://checkout.stripe.com/pay/cs_test_123

    BulkResponse:
      type: object
      properties:
        results:
          type: array
          items:
            type: object
            properties:
              row:
                type: integer
                example: 2
              status:
                type: string
                enum: [success, error]
                example: success
              slug:
                type: string
                example: abc123
              short_url:
                type: string
                format: uri
                example: https://hi4.in/r/abc123
              message:
                type: string
                example: Link created successfully
        total_processed:
          type: integer
          example: 10
        successful:
          type: integer
          example: 8
        failed:
          type: integer
          example: 2
        credits_used:
          type: integer
          example: 8

    Stats:
      type: object
      properties:
        user:
          type: object
          properties:
            total_links:
              type: integer
              example: 25
            total_clicks:
              type: integer
              example: 1500
            credits:
              type: number
              format: float
              example: 100.50
        global:
          type: object
          properties:
            total_links:
              type: integer
              example: 10000
            total_clicks:
              type: integer
              example: 100000
            public_links:
              type: integer
              example: 8000
            active_links:
              type: integer
              example: 9500

    Pagination:
      type: object
      properties:
        page:
          type: integer
          example: 1
        limit:
          type: integer
          example: 20
        total:
          type: integer
          example: 100
        pages:
          type: integer
          example: 5

    Error:
      type: object
      properties:
        error:
          type: boolean
          example: true
        message:
          type: string
          example: Invalid input data
        details:
          type: object
          additionalProperties: true
          example:
            field: "long_url is required"

tags:
  - name: Authentication
    description: User authentication and authorization
  - name: Links
    description: URL shortening and link management
  - name: Analytics
    description: Link analytics and statistics
  - name: Payments
    description: Payment processing and credits
  - name: Statistics
    description: User and global statistics
