openapi: 3.0.3
info:
  title: SellerLegend API
  description: |
    The SellerLegend API provides programmatic access to Amazon seller data, including sales, inventory, costs, and analytics.
    
    ## Authentication
    All API endpoints require OAuth 2.0 Bearer token authentication. Include the token in the Authorization header:
    ```
    Authorization: Bearer YOUR_ACCESS_TOKEN
    ```
    
    ## Base URL
    Production: `https://app.sellerlegend.com/api`
    
    ## Rate Limiting
    API requests are rate-limited. Please refer to response headers for current limits.
    
    ## Common Parameters
    Many endpoints support common filtering parameters:
    - `account_title`: Filter by specific account
    - `seller_id` + `marketplace_id`: Filter by seller and marketplace
    - `group_title`: Filter by account group
    - `filter_by` + `filter_value`: Filter by SKU, ASIN, or parent ASIN
    
  version: 1.0.0
  contact:
    name: SellerLegend Support
    email: support@sellerlegend.com
    url: https://sellerlegend.com
  license:
    name: Proprietary
    url: https://sellerlegend.com/terms

servers:
  - url: https://app.sellerlegend.com/api
    description: Production server
  - url: http://localhost:8000/api
    description: Development server

security:
  - bearerAuth: []

tags:
  - name: Authentication
    description: OAuth 2.0 authentication endpoints
  - name: User
    description: User profile and account management
  - name: Sales
    description: Sales orders and statistics
  - name: Inventory
    description: Inventory management and tracking
  - name: Costs
    description: Product cost management (COGS)
  - name: Reports
    description: Report generation and download
  - name: Connections
    description: Amazon SP-API and PPC connections
  - name: Warehouse
    description: Warehouse and inbound shipments
  - name: Supply Chain
    description: Restock suggestions and supply chain
  - name: Notifications
    description: System notifications

paths:
  /oauth/token:
    post:
      tags:
        - Authentication
      summary: Get access token
      description: |
        Exchange credentials for access token using OAuth 2.0 grant types.
        
        **Important:** The only supported grant type for full API access is Authorization Code.
        Direct access tokens can also be obtained through the SellerLegend web interface.
      security: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              oneOf:
                - $ref: '#/components/schemas/AuthorizationCodeGrant'
                - $ref: '#/components/schemas/RefreshTokenGrant'
      responses:
        '200':
          description: Successful authentication
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '422':
          $ref: '#/components/responses/ValidationError'

  /service-status:
    get:
      tags:
        - User
      summary: Check API service status
      description: Verify API is operational and user has access
      responses:
        '200':
          description: Service is active
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: Success
                  code:
                    type: integer
                    example: 200
                  message:
                    type: string
                    example: Active

  /user/me:
    get:
      tags:
        - User
      summary: Get current user
      description: Retrieve authenticated user's profile information
      responses:
        '200':
          description: User profile retrieved
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: Success
                  code:
                    type: integer
                    example: 200
                  message:
                    type: string
                    example: User
                  user:
                    $ref: '#/components/schemas/User'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '403':
          $ref: '#/components/responses/ForbiddenError'

  /user/accounts:
    get:
      tags:
        - User
      summary: List user accounts
      description: Get all Amazon seller accounts associated with the user
      responses:
        '200':
          description: Accounts retrieved
          content:
            application/json:
              schema:
                type: object
                properties:
                  accounts:
                    type: array
                    items:
                      $ref: '#/components/schemas/Account'
        '401':
          $ref: '#/components/responses/UnauthorizedError'

  /sales/orders:
    get:
      tags:
        - Sales
      summary: Get sales orders
      description: Retrieve sales orders with optional filtering
      parameters:
        - $ref: '#/components/parameters/AccountTitle'
        - $ref: '#/components/parameters/SellerId'
        - $ref: '#/components/parameters/MarketplaceId'
        - $ref: '#/components/parameters/GroupTitle'
        - name: per_page
          in: query
          required: true
          schema:
            type: integer
            enum: [250, 500, 1000, 2000]
          description: Number of results per page
        - name: start_date
          in: query
          schema:
            type: string
            format: date
            example: '2024-01-01'
          description: Start date (Y-m-d format)
        - name: end_date
          in: query
          schema:
            type: string
            format: date
            example: '2024-01-31'
          description: End date (Y-m-d format, max 1 month range)
        - name: sales_channel
          in: query
          schema:
            type: string
            enum: [amazon, non-amazon]
          description: Filter by sales channel
        - name: amazon_order_id
          in: query
          schema:
            type: string
          description: Filter by specific Amazon order ID
        - $ref: '#/components/parameters/FilterBy'
        - $ref: '#/components/parameters/FilterValue'
      responses:
        '200':
          description: Orders retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedOrders'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '422':
          $ref: '#/components/responses/ValidationError'

  /sales/statistics-dashboard:
    get:
      tags:
        - Sales
      summary: Get sales statistics
      description: Retrieve aggregated sales statistics dashboard data
      parameters:
        - $ref: '#/components/parameters/AccountTitle'
        - $ref: '#/components/parameters/SellerId'
        - $ref: '#/components/parameters/MarketplaceId'
        - $ref: '#/components/parameters/GroupTitle'
        - name: view_by
          in: query
          required: true
          schema:
            type: string
            enum: [product, date]
          description: View aggregation type
        - name: group_by
          in: query
          required: true
          schema:
            type: string
          description: Grouping criteria (depends on view_by)
        - name: per_page
          in: query
          required: true
          schema:
            type: integer
            enum: [500, 1000, 2000]
        - name: start_date
          in: query
          schema:
            type: string
            format: date
        - name: end_date
          in: query
          schema:
            type: string
            format: date
        - name: currency
          in: query
          schema:
            type: string
            example: USD
        - $ref: '#/components/parameters/FilterBy'
        - $ref: '#/components/parameters/FilterValue'
      responses:
        '200':
          description: Statistics retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DatatableResponse'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '422':
          $ref: '#/components/responses/ValidationError'

  /sales/per-day-per-product:
    get:
      tags:
        - Sales
      summary: Get daily product sales
      description: Retrieve sales data grouped by day and product
      parameters:
        - $ref: '#/components/parameters/AccountTitle'
        - $ref: '#/components/parameters/SellerId'
        - $ref: '#/components/parameters/MarketplaceId'
        - $ref: '#/components/parameters/GroupTitle'
        - name: per_page
          in: query
          required: true
          schema:
            type: integer
            enum: [500, 1000, 2000]
        - name: start_date
          in: query
          schema:
            type: string
            format: date
        - name: end_date
          in: query
          schema:
            type: string
            format: date
        - name: sales_channel
          in: query
          schema:
            type: string
            enum: [amazon, non-amazon]
        - name: currency
          in: query
          schema:
            type: string
        - $ref: '#/components/parameters/FilterBy'
        - $ref: '#/components/parameters/FilterValue'
      responses:
        '200':
          description: Daily sales data retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DatatableResponse'
        '401':
          $ref: '#/components/responses/UnauthorizedError'

  /sales/transactions:
    get:
      tags:
        - Sales
      summary: Get financial transactions
      description: Retrieve financial transaction records
      parameters:
        - $ref: '#/components/parameters/AccountTitle'
        - $ref: '#/components/parameters/SellerId'
        - $ref: '#/components/parameters/MarketplaceId'
        - $ref: '#/components/parameters/GroupTitle'
        - name: per_page
          in: query
          required: true
          schema:
            type: integer
            enum: [500, 1000, 2000]
        - name: start_date
          in: query
          schema:
            type: string
            format: date
        - name: end_date
          in: query
          schema:
            type: string
            format: date
        - $ref: '#/components/parameters/FilterBy'
        - $ref: '#/components/parameters/FilterValue'
      responses:
        '200':
          description: Transactions retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedTransactions'
        '401':
          $ref: '#/components/responses/UnauthorizedError'

  /inventory/list:
    get:
      tags:
        - Inventory
      summary: List inventory
      description: Get current inventory levels and product information
      parameters:
        - $ref: '#/components/parameters/AccountTitle'
        - $ref: '#/components/parameters/SellerId'
        - $ref: '#/components/parameters/MarketplaceId'
        - $ref: '#/components/parameters/GroupTitle'
        - name: per_page
          in: query
          required: true
          schema:
            type: integer
            enum: [20, 50, 100, 250, 500, 1000, 2000]
        - name: velocity_start_date
          in: query
          schema:
            type: string
            format: date
          description: Start date for velocity calculation
        - name: velocity_end_date
          in: query
          schema:
            type: string
            format: date
          description: End date for velocity calculation
        - $ref: '#/components/parameters/FilterBy'
        - $ref: '#/components/parameters/FilterValue'
      responses:
        '200':
          description: Inventory data retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DatatableResponse'
        '401':
          $ref: '#/components/responses/UnauthorizedError'

  /cogs/cost-periods:
    get:
      tags:
        - Costs
      summary: Get cost periods
      description: Retrieve cost period data for products
      parameters:
        - $ref: '#/components/parameters/AccountTitle'
        - $ref: '#/components/parameters/SellerId'
        - $ref: '#/components/parameters/MarketplaceId'
        - $ref: '#/components/parameters/GroupTitle'
        - name: sku
          in: query
          schema:
            type: string
          description: Product SKU (mutually exclusive with asin/parent_asin)
        - name: asin
          in: query
          schema:
            type: string
          description: Product ASIN (mutually exclusive with sku/parent_asin)
        - name: parent_asin
          in: query
          schema:
            type: string
          description: Parent ASIN (mutually exclusive with sku/asin)
      responses:
        '200':
          description: Cost periods retrieved
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ProductCostPeriods'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '422':
          $ref: '#/components/responses/ValidationError'

    post:
      tags:
        - Costs
      summary: Update cost periods
      description: Create or update cost periods for products
      parameters:
        - $ref: '#/components/parameters/AccountTitle'
        - $ref: '#/components/parameters/SellerId'
        - $ref: '#/components/parameters/MarketplaceId'
        - $ref: '#/components/parameters/GroupTitle'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [data]
              properties:
                sku:
                  type: string
                  description: Product SKU
                asin:
                  type: string
                  description: Product ASIN
                parent_asin:
                  type: string
                  description: Parent ASIN
                data:
                  type: array
                  items:
                    $ref: '#/components/schemas/CostPeriod'
      responses:
        '200':
          description: Cost periods updated
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: Success
                  message:
                    type: string
                    example: Cost periods updated successfully
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '422':
          $ref: '#/components/responses/ValidationError'

    delete:
      tags:
        - Costs
      summary: Delete cost periods
      description: Delete all cost periods for specified products
      parameters:
        - $ref: '#/components/parameters/AccountTitle'
        - $ref: '#/components/parameters/SellerId'
        - $ref: '#/components/parameters/MarketplaceId'
        - $ref: '#/components/parameters/GroupTitle'
        - name: sku
          in: query
          schema:
            type: string
        - name: asin
          in: query
          schema:
            type: string
        - name: parent_asin
          in: query
          schema:
            type: string
      responses:
        '200':
          description: Cost periods deleted
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: Success
                  message:
                    type: string
                    example: Cost periods deleted successfully
        '401':
          $ref: '#/components/responses/UnauthorizedError'

  /reports/request:
    post:
      tags:
        - Reports
      summary: Request report generation
      description: Submit a request to generate a new report
      parameters:
        - $ref: '#/components/parameters/AccountTitle'
        - $ref: '#/components/parameters/SellerId'
        - $ref: '#/components/parameters/MarketplaceId'
        - $ref: '#/components/parameters/GroupTitle'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                product_sku:
                  type: string
                  description: Generate report for specific SKU
                dps_date:
                  type: string
                  format: date
                  description: Generate report for specific date
                last_updated_date:
                  type: string
                  format: date
                  description: Generate report since last update
      responses:
        '200':
          description: Report request submitted
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: Success
                  message:
                    type: string
                    example: Request Submitted
                  report_id:
                    type: integer
                    example: 12345
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '422':
          $ref: '#/components/responses/ValidationError'

  /reports/status:
    get:
      tags:
        - Reports
      summary: Check report status
      description: Get the current status of a report generation request
      parameters:
        - name: report_id
          in: query
          required: true
          schema:
            type: integer
          description: Report ID from request
      responses:
        '200':
          description: Report status retrieved
          content:
            application/json:
              schema:
                type: object
                properties:
                  report_id:
                    type: integer
                  status:
                    type: string
                    enum: [processing, done, failed]
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'

  /reports/download:
    get:
      tags:
        - Reports
      summary: Download report
      description: Download a completed report as gzipped CSV
      parameters:
        - name: report_id
          in: query
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Report file download
          content:
            application/gzip:
              schema:
                type: string
                format: binary
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'

  /connections/list:
    get:
      tags:
        - Connections
      summary: List connections
      description: Get status of Amazon SP-API and PPC connections
      parameters:
        - $ref: '#/components/parameters/AccountTitle'
        - $ref: '#/components/parameters/SellerId'
        - $ref: '#/components/parameters/MarketplaceId'
        - $ref: '#/components/parameters/GroupTitle'
      responses:
        '200':
          description: Connection status retrieved
          content:
            application/json:
              schema:
                type: object
                properties:
                  connections:
                    type: array
                    items:
                      $ref: '#/components/schemas/ConnectionStatus'
        '401':
          $ref: '#/components/responses/UnauthorizedError'

  /warehouse/list:
    get:
      tags:
        - Warehouse
      summary: List warehouse inventory
      description: Get warehouse inventory data
      parameters:
        - $ref: '#/components/parameters/AccountTitle'
        - $ref: '#/components/parameters/SellerId'
        - $ref: '#/components/parameters/MarketplaceId'
        - $ref: '#/components/parameters/GroupTitle'
        - name: per_page
          in: query
          required: true
          schema:
            type: integer
            enum: [20, 50, 100, 250, 500, 1000, 2000]
        - $ref: '#/components/parameters/FilterBy'
        - $ref: '#/components/parameters/FilterValue'
      responses:
        '200':
          description: Warehouse data retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DatatableResponse'
        '401':
          $ref: '#/components/responses/UnauthorizedError'

  /warehouse/inbound-shipments:
    get:
      tags:
        - Warehouse
      summary: List inbound shipments
      description: Get inbound shipment information
      parameters:
        - $ref: '#/components/parameters/AccountTitle'
        - $ref: '#/components/parameters/SellerId'
        - $ref: '#/components/parameters/MarketplaceId'
        - $ref: '#/components/parameters/GroupTitle'
        - name: per_page
          in: query
          required: true
          schema:
            type: integer
            enum: [20, 50, 100, 250, 500, 1000, 2000]
        - $ref: '#/components/parameters/FilterBy'
        - $ref: '#/components/parameters/FilterValue'
      responses:
        '200':
          description: Inbound shipments retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DatatableResponse'
        '401':
          $ref: '#/components/responses/UnauthorizedError'

  /supply-chain/restock-suggestions:
    get:
      tags:
        - Supply Chain
      summary: Get restock suggestions
      description: Get product restocking recommendations
      parameters:
        - $ref: '#/components/parameters/AccountTitle'
        - $ref: '#/components/parameters/SellerId'
        - $ref: '#/components/parameters/MarketplaceId'
        - $ref: '#/components/parameters/GroupTitle'
        - name: per_page
          in: query
          required: true
          schema:
            type: integer
            enum: [500, 1000, 2000]
        - name: currency
          in: query
          schema:
            type: string
        - $ref: '#/components/parameters/FilterBy'
        - $ref: '#/components/parameters/FilterValue'
      responses:
        '200':
          description: Restock suggestions retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DatatableResponse'
        '401':
          $ref: '#/components/responses/UnauthorizedError'

  /notifications/list:
    get:
      tags:
        - Notifications
      summary: List notifications
      description: Get notifications from the last 24 hours
      parameters:
        - name: notification_type
          in: query
          required: true
          schema:
            type: string
          description: Type of notification to retrieve
      responses:
        '200':
          description: Notifications retrieved
          content:
            application/json:
              schema:
                type: object
                properties:
                  notifications:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                        payload_data:
                          type: object
                          description: Notification-specific data
        '401':
          $ref: '#/components/responses/UnauthorizedError'

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

  parameters:
    AccountTitle:
      name: account_title
      in: query
      description: Select by account title
      schema:
        type: string
        example: My Store US

    SellerId:
      name: seller_id
      in: query
      description: Amazon seller ID (requires marketplace_id)
      schema:
        type: string
        example: A1234567890

    MarketplaceId:
      name: marketplace_id
      in: query
      description: Amazon marketplace ID (requires seller_id)
      schema:
        type: string
        example: ATVPDKIKX0DER

    GroupTitle:
      name: group_title
      in: query
      description: Select by account group
      schema:
        type: string
        example: North America

    FilterBy:
      name: filter_by
      in: query
      schema:
        type: string
        enum: [sku, asin, parent_asin]
      description: Field to filter by

    FilterValue:
      name: filter_value
      in: query
      schema:
        type: string
      description: Value to filter for (requires filter_by)

  schemas:
    AuthorizationCodeGrant:
      type: object
      required: [grant_type, client_id, client_secret, code, redirect_uri]
      properties:
        grant_type:
          type: string
          enum: [authorization_code]
        client_id:
          type: string
        client_secret:
          type: string
        code:
          type: string
        redirect_uri:
          type: string
          format: uri

    RefreshTokenGrant:
      type: object
      required: [grant_type, refresh_token, client_id, client_secret]
      properties:
        grant_type:
          type: string
          enum: [refresh_token]
        refresh_token:
          type: string
        client_id:
          type: string
        client_secret:
          type: string

    TokenResponse:
      type: object
      properties:
        token_type:
          type: string
          example: Bearer
        expires_in:
          type: integer
          example: 3600
        access_token:
          type: string
        refresh_token:
          type: string

    User:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        email:
          type: string
          format: email
        status:
          type: string
        active:
          type: boolean

    Account:
      type: object
      properties:
        id:
          type: integer
        account_title:
          type: string
        country_code:
          type: string
        currency_code:
          type: string
        timezone:
          type: string
        marketplace:
          type: string
        seller_id:
          type: string

    PaginatedOrders:
      type: object
      properties:
        current_page:
          type: integer
        data:
          type: array
          items:
            type: object
            description: Order details
        total:
          type: integer
        per_page:
          type: integer
        last_page:
          type: integer

    PaginatedTransactions:
      type: object
      properties:
        current_page:
          type: integer
        data:
          type: array
          items:
            type: object
            description: Transaction details
        total:
          type: integer
        per_page:
          type: integer

    DatatableResponse:
      type: object
      properties:
        draw:
          type: integer
        recordsTotal:
          type: integer
        recordsFiltered:
          type: integer
        data:
          type: array
          items:
            type: object

    ProductCostPeriods:
      type: object
      properties:
        product_id:
          type: integer
        product_sku:
          type: string
        title:
          type: string
        asin:
          type: string
        parent_asin:
          type: string
        data:
          type: array
          items:
            $ref: '#/components/schemas/CostPeriod'

    CostPeriod:
      type: object
      properties:
        dates:
          type: object
          properties:
            from_date:
              type: string
              format: date
            to_date:
              type: string
              format: date
        cost_elements:
          type: array
          items:
            $ref: '#/components/schemas/CostElement'

    CostElement:
      type: object
      properties:
        cost_element:
          type: string
        provider:
          type: string
        notes:
          type: string
        total_amount:
          type: number
        currency:
          type: string
        conversion_rate:
          type: string
        units:
          type: integer
        amount:
          type: number

    ConnectionStatus:
      type: object
      properties:
        account_title:
          type: string
        seller_id:
          type: string
        region:
          type: string
        sp:
          type: object
          properties:
            status:
              type: string
              enum: [CONNECTED, DISCONNECTED, NOT_CONNECTED]
            last_connected_at:
              type: string
              format: date-time
            last_refreshed_at:
              type: string
              format: date-time
            brand_analytics_access:
              type: boolean
        ppc:
          type: object
          properties:
            status:
              type: string
              enum: [CONNECTED, DISCONNECTED, NOT_CONNECTED]
            last_connected_at:
              type: string
              format: date-time
            last_refreshed_at:
              type: string
              format: date-time
        marketplaces:
          type: object
          additionalProperties:
            type: object
            properties:
              account_title:
                type: string
              country:
                type: string
              marketplace_id:
                type: string
              status:
                type: string
              onboarding_progress:
                type: object
                properties:
                  orders:
                    type: string
                  inventory:
                    type: string
                  finances:
                    type: string
                  bsr:
                    type: string
                  product_history:
                    type: string

  responses:
    UnauthorizedError:
      description: Authentication required or token invalid
      content:
        application/json:
          schema:
            type: object
            properties:
              status:
                type: string
                example: Error
              code:
                type: integer
                example: 401
              message:
                type: string
                example: Unauthenticated

    ForbiddenError:
      description: Access denied - user lacks API access
      content:
        application/json:
          schema:
            type: object
            properties:
              status:
                type: string
                example: Error
              code:
                type: integer
                example: 403
              message:
                type: string
                example: Access Denied

    NotFoundError:
      description: Resource not found
      content:
        application/json:
          schema:
            type: object
            properties:
              status:
                type: string
                example: Error
              code:
                type: integer
                example: 404
              message:
                type: string
                example: Not Found

    ValidationError:
      description: Request validation failed
      content:
        application/json:
          schema:
            type: object
            properties:
              status:
                type: string
                example: Error
              code:
                type: integer
                example: 422
              message:
                type: string
                example: Validation Error
              errors:
                type: object
                additionalProperties:
                  type: array
                  items:
                    type: string