openapi: 3.1.0
info:
  title: Amanah Halal Compliance as a Service API
  version: 1.0.0-phase1
  summary: Phase 1 B2B, HR Risk, MCP catalog, and frontier discovery contracts.
  description: >
    Amanah.Finance B2B APIs expose listed-stock halal compliance, HR Risk,
    catalogue access, catalogue exports, MCP tool metadata, and a frontier
    discovery stock-check surface. Internal tier names are never exposed to
    clients; response fields are shaped by tenant entitlements.
servers:
  - url: https://api.amanah.finance
    description: Production
  - url: https://api.amanah.finance
    description: Sandbox or preview host, depending on provisioned API key
security:
  - B2BApiKey: []
tags:
  - name: Halal Screening
  - name: HR Risk
  - name: Catalogue
  - name: AI and MCP
paths:
  /v1/screen/stock/{ticker}:
    get:
      tags: [Halal Screening]
      operationId: getHalalStockScreening
      summary: Get halal compliance for one listed stock
      description: >
        Returns the tenant-shaped halal compliance response for a listed stock.
        The default response always promotes the Amanah Result plus the tenant's
        configured method where available. Phase 1 supports listed stocks only.
      parameters:
        - $ref: '#/components/parameters/Ticker'
      responses:
        '200':
          description: Stock screening result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HalalStockResponse'
              examples:
                minimal:
                  $ref: '#/components/examples/HalalStockMinimal'
                allMethods:
                  $ref: '#/components/examples/HalalStockAllMethods'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnsupportedInstrument'
  /v1/screen/stocks:
    post:
      tags: [Halal Screening]
      operationId: postBulkHalalStockScreening
      summary: Bulk screen listed stocks
      description: >
        Screens multiple listed-stock tickers synchronously. Request-level
        validation failures fail the whole request. Per-ticker failures are
        returned inside `items` while other tickers continue processing.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - type: object
                  required: [tickers]
                  properties:
                    tickers:
                      type: array
                      minItems: 1
                      items:
                        type: string
                      example: [AAPL, MSFT]
                - type: object
                  required: [holdings]
                  properties:
                    holdings:
                      type: array
                      minItems: 1
                      items:
                        type: object
                        required: [ticker]
                        properties:
                          ticker:
                            type: string
                      example:
                        - ticker: AAPL
                        - ticker: MSFT
      responses:
        '200':
          description: Bulk request succeeded or partially succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkHalalStockResponse'
        '400':
          $ref: '#/components/responses/ValidationError'
        '422':
          description: All per-ticker items failed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkHalalStockResponse'
  /v1/screen/stocks/catalog:
    get:
      tags: [Catalogue]
      operationId: getHalalStockCatalogue
      summary: List current halal compliance results for a market or exchange
      description: >
        Returns current pre-screened listed-stock rows for a market or exchange.
        Country filtering is intentionally not configured in Phase 1 and returns
        a graceful `COUNTRY_FILTER_NOT_CONFIGURED` error.
      parameters:
        - $ref: '#/components/parameters/Exchange'
        - $ref: '#/components/parameters/Market'
        - $ref: '#/components/parameters/Country'
        - $ref: '#/components/parameters/AssetClass'
        - $ref: '#/components/parameters/ResultFilter'
        - $ref: '#/components/parameters/Method'
        - $ref: '#/components/parameters/Page'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: Catalogue page.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HalalCatalogueResponse'
        '400':
          $ref: '#/components/responses/ValidationError'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/UnsupportedInstrument'
  /v1/screen/stocks/catalog/export:
    get:
      tags: [Catalogue]
      operationId: createHalalStockCatalogueExport
      summary: Create a CSV or JSON catalogue export job
      description: >
        Creates a Phase 1 inline catalogue export from precomputed rows. Object
        storage can replace inline job metadata later without changing this
        contract.
      parameters:
        - $ref: '#/components/parameters/Exchange'
        - $ref: '#/components/parameters/Market'
        - $ref: '#/components/parameters/Country'
        - $ref: '#/components/parameters/AssetClass'
        - $ref: '#/components/parameters/ResultFilter'
        - $ref: '#/components/parameters/Method'
        - name: format
          in: query
          schema:
            type: string
            enum: [csv, json]
            default: csv
        - $ref: '#/components/parameters/Limit'
      responses:
        '202':
          description: Export job accepted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CatalogueExportJobResponse'
  /v1/screen/stocks/catalog/export/jobs/{jobId}:
    get:
      tags: [Catalogue]
      operationId: getHalalStockCatalogueExportJob
      summary: Get catalogue export job status
      parameters:
        - $ref: '#/components/parameters/JobId'
      responses:
        '200':
          description: Export job status and inline content when completed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CatalogueExportJobResponse'
        '404':
          $ref: '#/components/responses/NotFound'
  /v1/screen/hr-risk/{ticker}:
    get:
      tags: [HR Risk]
      operationId: getHRRiskStockScore
      summary: Get HR Risk score for one listed stock
      description: >
        Returns the latest published visible HR Risk score when available, or a
        stable processing job reference when scoring is in progress. HR Risk is
        separate from halal compliance and has separate entitlements.
      parameters:
        - $ref: '#/components/parameters/Ticker'
      responses:
        '200':
          description: HR Risk result, status, or processing job.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HRRiskResponse'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
  /v1/screen/hr-risk/jobs/{jobId}:
    get:
      tags: [HR Risk]
      operationId: getHRRiskJob
      summary: Get HR Risk processing job status
      parameters:
        - $ref: '#/components/parameters/JobId'
      responses:
        '200':
          description: HR Risk job status.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HRRiskResponse'
  /v1/ai/frontier/stock-check:
    post:
      tags: [AI and MCP]
      operationId: postFrontierStockCheck
      summary: Frontier model discovery stock check
      description: >
        MVP discovery surface for questions such as "Is AAPL halal?". It only
        returns already-present current stored results, never triggers fresh
        screening, and does not store raw prompts or PII.
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                question:
                  type: string
                  example: Is AAPL halal?
                ticker:
                  type: string
                  example: AAPL
                company_name:
                  type: string
                  example: Apple
                anonymous_session_token:
                  type: string
      responses:
        '200':
          description: Answered, quota exhausted, unresolved, or unavailable response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FrontierStockCheckResponse'
        '404':
          description: Returned while frontier discovery is disabled.
  /v1/ai/mcp/tools:
    get:
      tags: [AI and MCP]
      operationId: getMCPToolCatalog
      summary: Get source-of-truth MCP tool catalogue
      description: >
        Returns Phase 1 MCP tool schemas and guardrails. This endpoint is a
        catalog foundation; the official MCP SDK server/runtime is packaged in a
        separate implementation pass.
      security: []
      responses:
        '200':
          description: Tool catalogue.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MCPToolCatalogResponse'
  /v1/mcp:
    post:
      tags: [AI and MCP]
      operationId: postMCPStreamableHTTP
      summary: Amanah MCP Streamable HTTP endpoint
      description: >
        Stateless MCP Streamable HTTP endpoint backed by the official TypeScript
        MCP SDK. The endpoint is protected by B2B API key auth, `mcp_enabled`,
        `mcp.access`, `POST /v1/mcp` endpoint entitlement, and per-tool
        `allowed_tools` checks.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
              description: MCP JSON-RPC request body.
      responses:
        '200':
          description: MCP JSON-RPC response.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
components:
  securitySchemes:
    B2BApiKey:
      type: http
      scheme: bearer
      bearerFormat: Amanah B2B API key
  parameters:
    Ticker:
      name: ticker
      in: path
      required: true
      schema:
        type: string
        pattern: '^[A-Za-z0-9.\-]{1,20}$'
      example: AAPL
    JobId:
      name: jobId
      in: path
      required: true
      schema:
        type: string
        format: uuid
    Exchange:
      name: exchange
      in: query
      schema:
        type: string
      example: NASDAQ
    Market:
      name: market
      in: query
      schema:
        type: string
      example: NYSE
    Country:
      name: country
      in: query
      schema:
        type: string
      description: Returns COUNTRY_FILTER_NOT_CONFIGURED in Phase 1.
    AssetClass:
      name: asset_class
      in: query
      schema:
        type: string
        default: listed_stock
      description: Phase 1 supports listed_stock only.
    ResultFilter:
      name: result
      in: query
      schema:
        type: string
        enum: [halal, non_compliant, all]
        default: all
    Method:
      name: method
      in: query
      schema:
        type: string
      description: Must be enabled for the tenant.
    Page:
      name: page
      in: query
      schema:
        type: integer
        minimum: 1
        default: 1
    Limit:
      name: limit
      in: query
      schema:
        type: integer
        minimum: 1
        maximum: 250
        default: 50
  responses:
    Unauthorized:
      description: Missing or invalid API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    Forbidden:
      description: Tenant, key, billing state, scope, endpoint, market, or entitlement is not allowed.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    NotFound:
      description: Requested ticker or job was not found.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    ValidationError:
      description: Invalid request body or query parameters.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    UnsupportedInstrument:
      description: Instrument or filter is coming soon for Phase 1.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
  schemas:
    Status:
      type: string
      enum: [success, partial_success, failed, error, scored, processing, queued, unavailable, quota_exhausted, ambiguous, not_found]
    Instrument:
      type: object
      required: [ticker, company_name, asset_class]
      properties:
        ticker:
          type: string
        company_name:
          type: string
        asset_class:
          type: string
          example: listed_stock
        exchange:
          type: [string, 'null']
        sector:
          type: [string, 'null']
        industry:
          type: [string, 'null']
    AmanahResult:
      type: object
      properties:
        result:
          type: string
          enum: [halal, non_compliant, doubtful, insufficient_data]
        compliant_methods_count:
          type: [integer, 'null']
        total_methods_count:
          type: [integer, 'null']
        compliance_percentage:
          type: [number, 'null']
    ConfiguredMethod:
      type: object
      nullable: true
      properties:
        method_id:
          type: string
        method_name:
          type: string
        result:
          type: string
          enum: [halal, non_compliant, doubtful, insufficient_data]
    HalalStockResponse:
      type: object
      required: [success, status, request_id, response_profile, instrument, amanah_result, screened_at, disclaimer]
      properties:
        success:
          type: boolean
        status:
          $ref: '#/components/schemas/Status'
        request_id:
          type: string
        response_profile:
          type: string
          enum: [minimal, all_methods, full_explainability]
        screening_result_id:
          type: string
        instrument:
          $ref: '#/components/schemas/Instrument'
        amanah_result:
          $ref: '#/components/schemas/AmanahResult'
        configured_method:
          $ref: '#/components/schemas/ConfiguredMethod'
        screened_at:
          type: string
          format: date-time
        methods:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/ConfiguredMethod'
        aggregate:
          type: object
          additionalProperties: true
        business_screen:
          type: [object, 'null']
          additionalProperties: true
        ratios_detail:
          type: object
          additionalProperties: true
        data_sources:
          type: object
          additionalProperties: true
        processing_time_ms:
          type: integer
        disclaimer:
          type: string
    BulkHalalStockResponse:
      type: object
      required: [success, status, request_id, response_profile, summary, items]
      properties:
        success:
          type: boolean
        status:
          type: string
          enum: [success, partial_success, failed]
        request_id:
          type: string
        response_profile:
          type: string
        summary:
          type: object
          properties:
            requested_count:
              type: integer
            success_count:
              type: integer
            failure_count:
              type: integer
        items:
          type: array
          items:
            type: object
            properties:
              input_index:
                type: integer
              ticker:
                type: string
              status:
                type: string
                enum: [success, error]
              result:
                $ref: '#/components/schemas/HalalStockResponse'
              error:
                type: object
                properties:
                  code:
                    type: string
                  message:
                    type: string
                  retryable:
                    type: boolean
    HalalCatalogueResponse:
      type: object
      required: [success, status, request_id, response_profile, filters, pagination, items]
      properties:
        success:
          type: boolean
        status:
          type: string
        request_id:
          type: string
        response_profile:
          type: string
        filters:
          type: object
          additionalProperties: true
        pagination:
          type: object
          additionalProperties: true
        items:
          type: array
          items:
            type: object
            additionalProperties: true
    CatalogueExportJobResponse:
      type: object
      required: [success, status, request_id, response_profile, job]
      properties:
        success:
          type: boolean
        status:
          type: string
          enum: [queued, processing, completed, failed, cancelled]
        request_id:
          type: string
        response_profile:
          type: string
        job:
          type: object
          additionalProperties: true
        download:
          type: [object, 'null']
          additionalProperties: true
        error:
          type: [object, 'null']
          additionalProperties: true
    HRRiskResponse:
      type: object
      required: [success, status, request_id, response_profile, instrument, disclaimer]
      properties:
        success:
          type: boolean
        status:
          type: string
          enum: [scored, unverifiable, queued, processing, failed, unavailable, locked, quota_exhausted, pending_review, under_review]
        request_id:
          type: string
        response_profile:
          type: string
          enum: [hr_risk_summary, hr_risk_full]
        instrument:
          $ref: '#/components/schemas/Instrument'
        screened_at:
          type: [string, 'null']
          format: date-time
        overall_confidence_label:
          type: [string, 'null']
        sensitive_context:
          type: boolean
        action_guidance:
          type: [object, 'null']
          additionalProperties: true
        result:
          type: [object, 'null']
          additionalProperties: true
        job:
          type: object
          additionalProperties: true
        details:
          type: object
          additionalProperties: true
        message:
          type: [string, 'null']
        disclaimer:
          type: string
    FrontierStockCheckResponse:
      type: object
      properties:
        success:
          type: boolean
        status:
          type: string
          enum: [answered, quota_exhausted, unavailable, ambiguous, not_found, error]
        request_id:
          type: string
        anonymous_session_token:
          type: string
        quota:
          type: object
          additionalProperties: true
        answer:
          type: object
          additionalProperties: true
        message:
          type: string
        candidates:
          type: array
          items:
            type: object
            additionalProperties: true
    MCPToolCatalogResponse:
      type: object
      properties:
        success:
          type: boolean
        status:
          type: string
        catalog_version:
          type: string
        tools:
          type: array
          items:
            type: object
            additionalProperties: true
    ErrorEnvelope:
      type: object
      required: [success, status, request_id, error]
      properties:
        success:
          type: boolean
          const: false
        status:
          type: string
          const: error
        request_id:
          type: string
        tenant_id:
          type: string
        environment:
          type: string
        error:
          type: object
          required: [code, message, retryable]
          properties:
            code:
              type: string
            message:
              type: string
            retryable:
              type: boolean
  examples:
    HalalStockMinimal:
      summary: Minimal B2B response
      value:
        success: true
        status: success
        request_id: req_123
        response_profile: minimal
        screening_result_id: 6df5d585-5e2f-4baa-98f8-3bcb6813472a
        instrument:
          ticker: AAPL
          company_name: Apple Inc.
          asset_class: listed_stock
          exchange: NASDAQ
          sector: Technology
          industry: Consumer Electronics
        amanah_result:
          result: halal
          compliant_methods_count: 7
          total_methods_count: 8
          compliance_percentage: 87.5
        configured_method:
          method_id: amanah_standard
          method_name: Amanah Standard
          result: halal
        screened_at: '2026-06-17T10:00:00.000Z'
        disclaimer: This response is for educational and compliance-information purposes only. It is not investment advice, financial advice, or a Shariah ruling.
    HalalStockAllMethods:
      summary: All methods response
      value:
        success: true
        status: success
        request_id: req_456
        response_profile: all_methods
        screening_result_id: 6df5d585-5e2f-4baa-98f8-3bcb6813472a
        instrument:
          ticker: AAPL
          company_name: Apple Inc.
          asset_class: listed_stock
          exchange: NASDAQ
          sector: Technology
          industry: Consumer Electronics
        amanah_result:
          result: halal
          compliant_methods_count: 7
          total_methods_count: 8
          compliance_percentage: 87.5
        configured_method:
          method_id: amanah_standard
          method_name: Amanah Standard
          result: halal
        screened_at: '2026-06-17T10:00:00.000Z'
        methods:
          amanah_standard:
            method_id: amanah_standard
            method_name: Amanah Standard
            result: halal
        aggregate:
          compliant_methods_count: 7
          total_methods_count: 8
          compliance_percentage: 87.5
        business_screen:
          result: halal
        disclaimer: This response is for educational and compliance-information purposes only. It is not investment advice, financial advice, or a Shariah ruling.
