# OpenAPI 3.0 Specification for Bill Tracking API
openapi: 3.0.3
info:
  title: Bill Tracking API
  description: Comprehensive RESTful API for legislative bill tracking, monitoring, and advocacy management
  version: '1.0'
  termsOfService: 'None'
  contact:
    email: api-support@engagifii.com
  license:
    name: Proprietary
    
servers:
  - url: https://engagifii-billtracking.azurewebsites.net
    description: Production server
    
security:
  - ApiKeyAuth: []
  - TenantAuth: []

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: api-version
      description: API version header (e.g., "1.0")
      
    TenantAuth:
      type: apiKey
      in: header
      name: tenant-code
      description: Unique tenant identifier for multi-tenant isolation
      
  parameters:
    ApiVersion:
      name: api-version
      in: path
      required: true
      schema:
        type: string
        default: '1.0'
      description: API version
      
    TenantCode:
      name: tenant-code
      in: header
      required: true
      schema:
        type: string
      description: Tenant identifier
      
    StateId:
      name: stateId
      in: path
      required: true
      schema:
        type: integer
        format: int64
      description: State identifier
      
    PageNumber:
      name: pageNumber
      in: query
      schema:
        type: integer
        minimum: 1
        default: 1
      description: Page number for pagination
      
    PageSize:
      name: pageSize
      in: query
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 50
      description: Number of items per page

  schemas:
    ActivityLogModel:
      type: object
      properties:
        id:
          type: integer
          format: int64
        userId:
          type: string
        action:
          type: string
        entityType:
          type: string
        entityId:
          type: string
        metadata:
          type: object
        timestamp:
          type: string
          format: date-time
          
    ActivityLogFilterModel:
      type: object
      properties:
        text:
          type: string
        userId:
          type: string
        startDate:
          type: string
          format: date
        endDate:
          type: string
          format: date
        pageNumber:
          type: integer
          minimum: 1
        pageSize:
          type: integer
          minimum: 1
          maximum: 100
        sortBy:
          type: string
        isAscending:
          type: boolean
          
    CampaignTemplatePostModel:
      type: object
      required:
        - name
        - messageTemplate
        - isActive
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
          maxLength: 255
        description:
          type: string
          maxLength: 2000
        targetAudience:
          type: string
        messageTemplate:
          type: string
        isActive:
          type: boolean
          
    BillCalendarFilterModel:
      type: object
      required:
        - startDate
        - endDate
      properties:
        startDate:
          type: string
          format: date
        endDate:
          type: string
          format: date
        stateIds:
          type: array
          items:
            type: integer
        sessionIds:
          type: array
          items:
            type: integer
        committeeIds:
          type: array
          items:
            type: integer
        eventTypes:
          type: array
          items:
            type: string
            enum: [HEARING, VOTE, COMMITTEE_MEETING, FLOOR_SESSION]
        includeArchived:
          type: boolean
          default: false
          
    BillCalendarViewModel:
      type: object
      properties:
        id:
          type: integer
          format: int64
        billId:
          type: integer
          format: int64
        billNumber:
          type: string
        title:
          type: string
        eventDate:
          type: string
          format: date-time
        eventType:
          type: string
        location:
          type: string
        committee:
          type: string
        state:
          type: string
        status:
          type: string
          
    CapitolReportPostModel:
      type: object
      required:
        - title
        - stateId
        - reportDate
      properties:
        id:
          type: integer
          format: int64
        title:
          type: string
          maxLength: 500
        stateId:
          type: integer
          format: int64
        reportDate:
          type: string
          format: date
        content:
          type: string
        billIds:
          type: array
          items:
            type: integer
            format: int64
        reportType:
          type: integer
          enum: [1, 2, 3, 4, 5, 6]
        isPublished:
          type: boolean
          default: false
          
    StateModel:
      type: object
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
        abbreviation:
          type: string
          maxLength: 2
        isActive:
          type: boolean
          
    SessionModel:
      type: object
      properties:
        id:
          type: integer
          format: int64
        stateId:
          type: integer
          format: int64
        name:
          type: string
        startDate:
          type: string
          format: date
        endDate:
          type: string
          format: date
        isActive:
          type: boolean
          
    CommitteeModel:
      type: object
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
        chamber:
          type: string
          enum: [HOUSE, SENATE, JOINT]
        stateId:
          type: integer
          format: int64
        isActive:
          type: boolean
          
    PagingModel:
      type: object
      properties:
        pageNumber:
          type: integer
        pageSize:
          type: integer
        totalRecords:
          type: integer
        totalPages:
          type: integer
          
    ErrorResponse:
      type: object
      properties:
        error:
          type: string
        message:
          type: string
        details:
          type: object
          properties:
            code:
              type: string
            timestamp:
              type: string
              format: date-time
            requestId:
              type: string

  responses:
    BadRequest:
      description: Bad Request - Invalid parameters
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
            
    Unauthorized:
      description: Unauthorized - Authentication required
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
            
    Forbidden:
      description: Forbidden - Insufficient permissions
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
            
    NotFound:
      description: Not Found - Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
            
    RateLimited:
      description: Too Many Requests - Rate limit exceeded
      headers:
        X-RateLimit-Limit:
          schema:
            type: integer
        X-RateLimit-Remaining:
          schema:
            type: integer
        X-RateLimit-Reset:
          schema:
            type: integer
        Retry-After:
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'

paths:
  /api/{api-version}/activity/log/save:
    post:
      tags:
        - Activity
      summary: Save activity log entry
      operationId: saveActivityLog
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - $ref: '#/components/parameters/TenantCode'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ActivityLogModel'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: boolean
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
          
  /api/{api-version}/activity/log/list:
    post:
      tags:
        - Activity
      summary: List activity logs with filtering
      operationId: listActivityLogs
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - $ref: '#/components/parameters/TenantCode'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ActivityLogFilterModel'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: object
                properties:
                  collection:
                    type: array
                    items:
                      $ref: '#/components/schemas/ActivityLogModel'
                  pagingModel:
                    $ref: '#/components/schemas/PagingModel'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
          
  /api/{api-version}/Advocacy/getChampaignTemplate/{id}:
    get:
      tags:
        - Advocacy
      summary: Get campaign template by ID
      operationId: getCampaignTemplate
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - $ref: '#/components/parameters/TenantCode'
        - name: id
          in: path
          required: true
          schema:
            type: integer
            format: int64
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignTemplatePostModel'
        '404':
          $ref: '#/components/responses/NotFound'
          
  /api/{api-version}/Advocacy/saveChampaignTemplate:
    post:
      tags:
        - Advocacy
      summary: Save campaign template
      operationId: saveCampaignTemplate
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - $ref: '#/components/parameters/TenantCode'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CampaignTemplatePostModel'
      responses:
        '200':
          description: Success - Returns created template ID
          content:
            application/json:
              schema:
                type: integer
                format: int64
        '400':
          $ref: '#/components/responses/BadRequest'
          
  /api/{api-version}/bill/event/calendar:
    post:
      tags:
        - Bill Events
      summary: Get bill calendar events
      operationId: getBillCalendar
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - $ref: '#/components/parameters/TenantCode'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BillCalendarFilterModel'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/BillCalendarViewModel'
        '400':
          $ref: '#/components/responses/BadRequest'
          
  /api/{api-version}/dropdown/states:
    get:
      tags:
        - Dropdown Data
      summary: Get list of states
      operationId: getStates
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - $ref: '#/components/parameters/TenantCode'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/StateModel'
        '401':
          $ref: '#/components/responses/Unauthorized'
          
  /api/{api-version}/dropdown/sessions:
    get:
      tags:
        - Dropdown Data
      summary: Get list of sessions
      operationId: getSessions
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - $ref: '#/components/parameters/TenantCode'
        - name: stateId
          in: query
          schema:
            type: integer
            format: int64
          description: Filter by state
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SessionModel'
        '401':
          $ref: '#/components/responses/Unauthorized'
          
  /api/{api-version}/dropdown/committees:
    get:
      tags:
        - Dropdown Data
      summary: Get list of committees
      operationId: getCommittees
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - $ref: '#/components/parameters/TenantCode'
        - name: stateId
          in: query
          schema:
            type: integer
            format: int64
        - name: sessionId
          in: query
          schema:
            type: integer
            format: int64
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/CommitteeModel'
        '401':
          $ref: '#/components/responses/Unauthorized'
          
  /api/{api-version}/CapitolReport/save-report/{StateId}:
    post:
      tags:
        - Capitol Reports
      summary: Save capitol report
      operationId: saveCapitolReport
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - $ref: '#/components/parameters/TenantCode'
        - $ref: '#/components/parameters/StateId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CapitolReportPostModel'
      responses:
        '200':
          description: Success - Returns created report ID
          content:
            application/json:
              schema:
                type: integer
                format: int64
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'

tags:
  - name: Activity
    description: Activity logging and audit trail endpoints
  - name: Advocacy
    description: Campaign and advocacy management endpoints
  - name: Bill Events
    description: Bill calendar and event management endpoints
  - name: Capitol Reports
    description: Legislative report generation endpoints
  - name: Dropdown Data
    description: Reference data for UI dropdowns
    
externalDocs:
  description: Full API Documentation
  url: https://developers.engagifii.com/docs