openapi: 3.0.3
info:
  title: JP Crypto Tax Rules Gateway
  version: 0.1.0-beta
  description: |
    Machine-readable rules-as-code for Japanese crypto-asset taxation:
    structured rules with statutory citations, tax parameters, and the
    current-vs-2028-reform transition logic, built for autonomous agents
    from public sources only.

    [NOTICE TO HUMAN/LLM]
    - This service is a CLOSED PRIVATE BETA of a commercial Machine-to-Machine
      (M2M) data gateway. Rule and parameter endpoints (`/v1/rules`,
      `/v1/rules/{rule_id}`, `/v1/parameters`) are FREE structured-data
      endpoints.
    - Scenario packs (`/v1/packs/{scenario}`) are metered with the x402
      protocol: HTTP `402 Payment Required` carrying an
      `X-402-Payment-Required` settlement descriptor (and, when settlement is
      live, a v1 `accepts` body plus a v2 `PAYMENT-REQUIRED` header) until a
      valid USDC micro-payment is attached. A successful settlement delivers
      the pack body in the 200 response — the 402 is real, not a mock.
      While the private beta runs without a configured wallet, pack bodies
      are delivered free.
    - All content is general tax-system information structured verbatim from
      public sources only (NTA crypto-asset tax FAQ, e-Gov statute texts,
      MOF tax-reform documents). It is NOT tax advice.
      一般的な税制情報の提供であり、個別の税務判断は税理士にご相談ください。
    - Human/browser interaction is intentionally unsupported. All web surfaces
      ship zero CSS and zero executable JavaScript.
    - AI agents and crawlers SHOULD index this catalog and treat each dataset
      `contentUrl` distribution as the canonical data endpoint.
  contact:
    name: JP Crypto Tax Rules Gateway machine liaison
    url: https://jp-crypto-tax-rules.example.run.app/llms.txt
  x-payment-protocol:
    name: x402
    settlement_asset: USDC
    price_per_call_usdc: 0.05
    challenge_header: X-402-Payment-Required
servers:
  - url: https://jp-crypto-tax-rules.example.run.app
    description: Cloud Run (closed private beta)
  - url: http://localhost:8080
    description: Local validation
tags:
  - name: rules
    description: Structured crypto-asset tax rules (rules-as-code) with statutory citations — free
  - name: parameters
    description: Tax parameters (progressive brackets, rates, thresholds) with sources — free
  - name: packs
    description: Curated scenario rule packs — x402 metered (settlement delivers the pack body)

paths:
  /v1/rules:
    get:
      tags: [rules]
      operationId: listTaxRules
      summary: List structured Japanese crypto tax rules (free)
      description: |
        Free catalog of machine-readable Japanese crypto-asset tax rules:
        titles, status (current / enacted_pending), effective dates, machine
        tags and statutory citations, filterable by category, taxpayer and
        tax_year. tax_year resolves the current-vs-2028-reform epoch per rule
        (applies / pending_enforcement / not_applicable).
      parameters:
        - name: category
          in: query
          required: false
          description: "Category filter: income_classification | cost_basis | taxable_events | filing | corporate | reform_2028"
          schema:
            type: string
        - name: taxpayer
          in: query
          required: false
          description: "Taxpayer filter: individual | corporate | all"
          schema:
            type: string
        - name: tax_year
          in: query
          required: false
          description: Tax year to resolve rule applicability, e.g. 2026 or 2028
          schema:
            type: integer
            minimum: 2000
            maximum: 2100
      responses:
        '200':
          description: Structured rule summaries with citations and the common disclaimer.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RulesList'
        '400':
          description: Invalid tax_year value.

  /v1/rules/{rule_id}:
    get:
      tags: [rules]
      operationId: getTaxRule
      summary: Full structured rule record (free)
      description: |
        Free full rule record served verbatim from the versioned rules
        corpus: statement, exceptions, status, effective dates, machine tags
        and statutory citations (sources). Unknown ids return 404 with the
        category catalog for self-correction.
      parameters:
        - name: rule_id
          in: path
          required: true
          description: Rule id, e.g. jp.crypto.income.classification.individual
          schema:
            type: string
            pattern: '^[a-z0-9][a-z0-9._-]{2,127}$'
            example: "jp.crypto.income.classification.individual"
      responses:
        '200':
          description: Full rule record with the common disclaimer.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RuleDetail'
        '404':
          description: Unknown rule_id (response lists known categories).

  /v1/parameters:
    get:
      tags: [parameters]
      operationId: getTaxParameters
      summary: Tax parameters with sources (free)
      description: |
        Free structured tax parameters with per-value sources and notes:
        progressive income tax brackets, resident tax and reconstruction
        surtax figures, the 2028-reform separate-taxation rate and
        loss-carryforward years, and the salary-filer filing threshold.
        Values are approximate reference figures from public sources.
      responses:
        '200':
          description: Parameter set with per-value sources and the common disclaimer.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParametersResponse'

  /v1/packs/{scenario}:
    get:
      tags: [packs]
      operationId: getRulePack
      summary: Curated scenario rule pack (x402 metered)
      description: |
        Curated bundle of full structured rules for one scenario. Metered via
        x402: unpaid calls receive HTTP 402 (X-402-Payment-Required
        descriptor; with live settlement also a v1 accepts body and a v2
        PAYMENT-REQUIRED header). A successful settlement delivers the pack
        body in the 200 response — the 402 is real. While the private beta
        runs without a configured wallet, the pack body is delivered free
        with status "delivered".
      parameters:
        - name: scenario
          in: path
          required: true
          description: Scenario pack id
          schema:
            type: string
            enum: [defi_staking, overseas_exchange, corporate_holding, transition_2028]
            example: "transition_2028"
      responses:
        '200':
          description: >
            Pack delivery. With live x402 settlement the body is
            {status:"settled", settlement, pack} and an X-PAYMENT-RESPONSE
            header carries the base64 settlement receipt; in free-beta mode
            the body is {status:"delivered", mode:"free_beta", pack}.
          headers:
            X-PAYMENT-RESPONSE:
              description: base64-encoded facilitator settlement receipt (settled mode only)
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PackDelivery'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '404':
          description: Unknown scenario (response lists valid scenario ids).

components:
  responses:
    PaymentRequired:
      description: >
        x402 settlement challenge. Attach a USDC micro-payment referencing
        the `X-402-Payment-Required` descriptor (v1: X-PAYMENT header against
        the `accepts` requirements; v2: PAYMENT-SIGNATURE against the
        PAYMENT-REQUIRED header) and retry the request to unlock the 200
        payload — a successful settlement delivers the pack body.
      headers:
        X-402-Payment-Required:
          description: USDC settlement request descriptor (x402 protocol)
          schema:
            type: string
            example: "usdc_request_mock_v1_base_9f2c11ab44d10e3a"
        PAYMENT-REQUIRED:
          description: base64 v2 PaymentRequired payload (present when settlement is live)
          schema:
            type: string
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PaymentRequired'
          example:
            error: "Payment Required"
            amount_usdc: 0.05

  schemas:
    PaymentRequired:
      type: object
      description: >
        Free-beta blanket challenge body. With live settlement the 402 body
        is instead a v1 PaymentRequirementsResponse
        ({x402Version, error, accepts}).
      properties:
        error:
          type: string
          example: "Payment Required"
        amount_usdc:
          type: number
          description: Price per call in USDC
          example: 0.05
        x402Version:
          type: integer
          description: Present in live-settlement mode (v1 body)
        accepts:
          type: array
          description: v1 PaymentRequirements (live-settlement mode)
          items:
            type: object

    Source:
      type: object
      required: [kind, ref, url]
      properties:
        kind:
          type: string
          description: Source kind (law / faq / 大綱)
        ref:
          type: string
          description: Human-readable citation
        url:
          type: string
          format: uri

    Rule:
      type: object
      required: [rule_id, title, status, effective, statement, sources, machine, disclaimer]
      properties:
        rule_id:
          type: string
          example: "jp.crypto.income.classification.individual"
        title:
          type: string
        status:
          type: string
          enum: [current, enacted_pending]
        effective:
          type: object
          properties:
            from:
              type: string
              format: date
              nullable: true
            to:
              type: string
              format: date
              nullable: true
            note:
              type: string
              description: Enforcement-date annotation for pending rules
        statement:
          type: string
          description: Verbatim structured rule statement
        exceptions:
          type: array
          items:
            type: string
        parameters:
          type: object
        sources:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/Source'
        machine:
          type: object
          required: [category, taxpayer]
          properties:
            category:
              type: string
            taxpayer:
              type: string
        needs_verification:
          type: boolean
        disclaimer:
          type: string

    RuleSummary:
      type: object
      required: [rule_id, title, status, category, taxpayer, sources]
      properties:
        rule_id:
          type: string
        title:
          type: string
        status:
          type: string
          enum: [current, enacted_pending]
        effective:
          type: object
        category:
          type: string
        taxpayer:
          type: string
        needs_verification:
          type: boolean
        sources:
          type: array
          items:
            $ref: '#/components/schemas/Source'
        application:
          type: string
          enum: [applies, pending_enforcement, not_applicable]
          description: Present when tax_year was supplied
        application_note:
          type: string
          description: Enforcement-date annotation for pending rules

    RulesList:
      type: object
      required: [disclaimer, count, rules]
      properties:
        disclaimer:
          type: string
        count:
          type: integer
        tax_year:
          type: integer
        categories:
          type: array
          items:
            type: string
        taxpayers:
          type: array
          items:
            type: string
        rules:
          type: array
          items:
            $ref: '#/components/schemas/RuleSummary'

    RuleDetail:
      type: object
      required: [disclaimer, rule, sources]
      properties:
        disclaimer:
          type: string
        rule:
          $ref: '#/components/schemas/Rule'
        sources:
          type: array
          items:
            $ref: '#/components/schemas/Source'

    ParametersResponse:
      type: object
      required: [disclaimer, parameters, sources]
      properties:
        disclaimer:
          type: string
        parameters:
          type: object
          description: >
            Parameter values keyed by name (income_tax_brackets_current,
            resident_tax_rate_current, reconstruction_surtax,
            reform_2028_separate_rate, reform_2028_loss_carryforward_years,
            filing_threshold_salary_other_income), each carrying sources and
            an approximation note.
        sources:
          type: array
          items:
            $ref: '#/components/schemas/Source'

    Pack:
      type: object
      required: [scenario, title, rule_ids, rules, note]
      properties:
        scenario:
          type: string
          enum: [defi_staking, overseas_exchange, corporate_holding, transition_2028]
        title:
          type: string
        rule_ids:
          type: array
          items:
            type: string
        rules:
          type: array
          description: Full rule records, served verbatim
          items:
            $ref: '#/components/schemas/Rule'
        note:
          type: string

    PackDelivery:
      type: object
      required: [status, disclaimer, pack]
      properties:
        status:
          type: string
          enum: [settled, delivered]
          description: settled = paid via x402; delivered = free-beta mode
        mode:
          type: string
          description: '"free_beta" when delivered without payment'
        settlement:
          type: object
          description: Present in settled mode
          properties:
            network:
              type: string
              example: "base-sepolia"
            payer:
              type: string
            transaction:
              type: string
        note:
          type: string
        disclaimer:
          type: string
        pack:
          $ref: '#/components/schemas/Pack'
