openapi: 3.1.0
info:
  title: TensorFeed API
  version: 1.0.0
  summary: Real-time AI ecosystem data for humans and agents
  description: |
    TensorFeed.ai is a free, no-auth JSON API for AI news, service status, model pricing, GPU pricing, agent directories, and AFTA (Agent Fair-Trade Agreement) data, plus a paid premium tier (USDC on Base, x402 compatible) for ranked model routing, search, history series, watches, and computed intelligence.

    Highlights for AI agents:
    - No API key on free endpoints. CORS enabled. Rate limit 120 req/min/IP.
    - AFTA-certified: code-enforced no-charge on 5xx, circuit breaker, schema failure, or stale data. Every paid response carries an Ed25519-signed receipt.
    - Premium tier accepts pay-per-call USDC on Base, no accounts, no traditional processors.
    - Machine-readable manifests at /.well-known/agent-fair-trade.json and /llms.txt.

    Full endpoint catalog at /api/meta. Standard at https://tensorfeed.ai/agent-fair-trade.

  termsOfService: https://tensorfeed.ai/terms
  contact:
    name: TensorFeed Support
    email: evan@tensorfeed.ai
    url: https://tensorfeed.ai/developers
  license:
    name: API content licensed for inference-only use
    url: https://tensorfeed.ai/agent-fair-trade
  x-logo:
    url: https://tensorfeed.ai/tensorfeed-logo.png
    altText: TensorFeed.ai

servers:
  - url: https://tensorfeed.ai
    description: Production

security: []

tags:
  - name: Discovery
    description: Service metadata, health, and the canonical endpoint catalog.
  - name: News
    description: AI news aggregated from all major sources.
  - name: Status
    description: Real-time operational status for major AI services.
  - name: Models
    description: Model specs, pricing, and benchmarks.
  - name: Agents
    description: Agent directory and live agent traffic on TensorFeed itself.
  - name: GPU
    description: GPU rental marketplace pricing.
  - name: MCP
    description: Model Context Protocol registry telemetry.
  - name: History
    description: Daily snapshots for time-series analysis.
  - name: Probe
    description: Active LLM endpoint latency probes.
  - name: AFTA
    description: 'Agent Fair-Trade Agreement: standard, adopters, receipts.'
  - name: Payment
    description: x402-compatible USDC-on-Base credit purchase + balance.
  - name: Premium
    description: Pay-per-call computed intelligence (requires bearer token).

paths:
  /api/meta:
    get:
      tags: [Discovery]
      summary: Canonical endpoint catalog and self-description
      operationId: getMeta
      description: |
        The authoritative listing of every public endpoint, including AFTA self-description, freshness SLAs, rate limits, chaos-engineering headers, and the supportive-sites network. The first thing an agent should read.
      responses:
        '200':
          description: Site metadata and full endpoint catalog
          content:
            application/json:
              schema: { type: object, properties: { ok: { type: boolean }, site: { type: string }, api: { type: object } } }

  /api/health:
    get:
      tags: [Discovery]
      summary: Service health and freshness summary
      operationId: getHealth
      responses:
        '200':
          description: Counts and last-updated timestamps for every data subsystem
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok: { type: boolean }
                  timestamp: { type: string, format: date-time }
                  news: { type: object }
                  models: { type: object }
                  benchmarks: { type: object }
                  agents: { type: object }

  /api/news:
    get:
      tags: [News]
      summary: Aggregated AI news articles
      operationId: getNews
      parameters:
        - in: query
          name: category
          schema: { type: string, example: OpenAI }
          description: Filter by source category (OpenAI, Anthropic, Google, etc.)
        - in: query
          name: limit
          schema: { type: integer, default: 50, minimum: 1, maximum: 200 }
      responses:
        '200':
          description: Recent articles, snippets clipped to ~200 chars, prompt-injection sanitized.
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok: { type: boolean }
                  count: { type: integer }
                  articles:
                    type: array
                    items: { $ref: '#/components/schemas/NewsArticle' }
                  sanitization: { type: string, example: enabled }

  /api/agents/news:
    get:
      tags: [News, Agents]
      summary: Agent-friendly compact news payload
      operationId: getAgentsNews
      description: Lighter article payload tuned for LLM context windows. Same source data as /api/news.
      responses:
        '200':
          description: Compact news objects.
          content:
            application/json:
              schema: { type: object }

  /api/feed.xml:
    get:
      tags: [News]
      summary: RSS 2.0 feed of all AI news
      operationId: getFeedRss
      responses:
        '200':
          description: RSS XML
          content:
            application/rss+xml: { schema: { type: string } }

  /api/feed.json:
    get:
      tags: [News]
      summary: JSON Feed 1.1
      operationId: getFeedJson
      responses:
        '200':
          description: JSON Feed
          content:
            application/feed+json: { schema: { type: object } }

  /api/status:
    get:
      tags: [Status]
      summary: Operational status for major AI services
      operationId: getStatus
      responses:
        '200':
          description: Per-service status with components
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok: { type: boolean }
                  services:
                    type: array
                    items: { $ref: '#/components/schemas/StatusService' }

  /api/status/summary:
    get:
      tags: [Status]
      summary: Lightweight status counts for dashboards
      operationId: getStatusSummary
      responses:
        '200':
          description: Counts of operational, degraded, and down services
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok: { type: boolean }
                  summary:
                    type: object
                    properties:
                      total: { type: integer }
                      operational: { type: integer }
                      degraded: { type: integer }
                      down: { type: integer }

  /api/models:
    get:
      tags: [Models]
      summary: AI model pricing and specs
      operationId: getModels
      description: Input/output cost per 1M tokens, context window, capabilities, across 200+ models from major labs.
      responses:
        '200':
          description: Provider-grouped model list
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok: { type: boolean }
                  lastUpdated: { type: string }
                  providers:
                    type: array
                    items: { type: object }

  /api/agents/pricing:
    get:
      tags: [Models]
      summary: Agent-friendly compact pricing payload
      operationId: getAgentsPricing
      responses:
        '200':
          description: Compact pricing list
          content:
            application/json:
              schema: { type: object }

  /api/benchmarks:
    get:
      tags: [Models]
      summary: Public benchmark scores for major models
      operationId: getBenchmarks
      responses:
        '200':
          description: Benchmark catalog with per-model scores
          content:
            application/json:
              schema: { type: object, properties: { ok: { type: boolean }, benchmarks: { type: array, items: { type: object } } } }

  /api/agents/directory:
    get:
      tags: [Agents]
      summary: Curated directory of AI agents and frameworks
      operationId: getAgentsDirectory
      responses:
        '200':
          description: Categorized directory of production-grade agents.
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok: { type: boolean }
                  source: { type: string }
                  categories: { type: array, items: { type: object } }
                  agents: { type: array, items: { type: object } }

  /api/agents/activity:
    get:
      tags: [Agents]
      summary: Live AI bot traffic on TensorFeed
      operationId: getAgentActivity
      description: Last hits per known AI bot user-agent (ClaudeBot, GPTBot, Applebot, etc). Useful for understanding crawler adoption.
      responses:
        '200':
          description: Recent agent hits
          content:
            application/json:
              schema:
                type: object
                properties:
                  today_count: { type: integer }
                  last_updated: { type: string, format: date-time }
                  recent:
                    type: array
                    items:
                      type: object
                      properties:
                        bot: { type: string }
                        endpoint: { type: string }
                        timestamp: { type: string, format: date-time }

  /api/podcasts:
    get:
      tags: [News]
      summary: Recent AI podcast episodes
      operationId: getPodcasts
      responses:
        '200':
          description: Episode list with show, title, published date.
          content:
            application/json:
              schema: { type: object }

  /api/trending-repos:
    get:
      tags: [News]
      summary: Trending GitHub repos in AI
      operationId: getTrendingRepos
      responses:
        '200':
          description: Top repos by recent star velocity in AI/ML topics.
          content:
            application/json:
              schema: { type: object }

  /api/gpu/pricing:
    get:
      tags: [GPU]
      summary: Current GPU rental pricing snapshot
      operationId: getGpuPricing
      responses:
        '200':
          description: Aggregated pricing across cloud GPU marketplaces.
          content:
            application/json:
              schema: { type: object }

  /api/gpu/pricing/cheapest:
    get:
      tags: [GPU]
      summary: Cheapest current offer for a canonical GPU
      operationId: getGpuPricingCheapest
      parameters:
        - in: query
          name: gpu
          required: true
          schema: { type: string, example: H100 }
          description: Canonical GPU id (H100, H200, A100-80GB, RTX-4090, etc.)
        - in: query
          name: type
          schema: { type: string, enum: [on_demand, spot], default: on_demand }
      responses:
        '200':
          description: Top 3 cheapest offers right now.
          content:
            application/json:
              schema: { type: object }

  /api/mcp/registry/snapshot:
    get:
      tags: [MCP]
      summary: Daily MCP server registry summary
      operationId: getMcpRegistrySnapshot
      description: Today's count + 1-day delta of the official MCP server registry. Refreshed daily.
      responses:
        '200':
          description: Latest registry summary
          content:
            application/json:
              schema: { type: object, properties: { ok: { type: boolean }, summary: { type: object } } }

  /api/probe/latest:
    get:
      tags: [Probe]
      summary: Last 24h of LLM endpoint latency probes
      operationId: getProbeLatest
      description: Active probe results (TTFB, total) per provider. Refreshed every 15 min.
      responses:
        '200':
          description: Probe summary
          content:
            application/json:
              schema: { type: object }

  /api/history:
    get:
      tags: [History]
      summary: Index of historical daily snapshots
      operationId: getHistoryIndex
      responses:
        '200':
          description: Available date ranges per snapshot type.
          content:
            application/json:
              schema: { type: object }

  /api/history/{date}/{type}:
    get:
      tags: [History]
      summary: Read one historical snapshot
      operationId: getHistorySnapshot
      parameters:
        - in: path
          name: date
          required: true
          schema: { type: string, pattern: '^\d{4}-\d{2}-\d{2}$', example: '2026-05-01' }
        - in: path
          name: type
          required: true
          schema: { type: string, enum: [pricing, benchmarks, status, news, mcp-registry, probe, gpu-pricing] }
      responses:
        '200':
          description: Snapshot payload
          content:
            application/json:
              schema: { type: object }
        '404': { description: Snapshot not found }

  /api/afta/adopters:
    get:
      tags: [AFTA]
      summary: Machine-readable AFTA adopter directory
      operationId: getAftaAdopters
      description: Public list of sites that publish a /.well-known/agent-fair-trade.json manifest. Not authoritative; agents should verify each manifest directly.
      responses:
        '200':
          description: Adopter list
          content:
            application/json:
              schema: { type: object }

  /api/payment/info:
    get:
      tags: [Payment]
      summary: Wallet, pricing, and operator info
      operationId: getPaymentInfo
      responses:
        '200':
          description: Payment metadata for buying credits.
          content:
            application/json:
              schema: { type: object }

  /api/payment/buy-credits:
    post:
      tags: [Payment]
      summary: Initiate a credit purchase
      operationId: postBuyCredits
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [amount_usd]
              properties:
                amount_usd: { type: number, minimum: 1, example: 5 }
                sender_wallet: { type: string, example: '0x...' }
      responses:
        '200':
          description: Quote with credits and instructions to send USDC on Base.
          content:
            application/json:
              schema: { type: object }

  /api/payment/confirm:
    post:
      tags: [Payment]
      summary: Confirm a USDC payment and receive bearer token
      operationId: postPaymentConfirm
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [tx_hash]
              properties:
                tx_hash: { type: string, example: '0xabc...' }
      responses:
        '200':
          description: Bearer token + credit balance.
          content:
            application/json:
              schema: { type: object }

  /api/payment/balance:
    get:
      tags: [Payment]
      summary: Token balance and usage
      operationId: getPaymentBalance
      security: [{ BearerAuth: [] }]
      responses:
        '200':
          description: Credits remaining, total spent, recent calls.
          content:
            application/json:
              schema: { type: object }

  /api/payment/no-charge-stats:
    get:
      tags: [AFTA, Payment]
      summary: Public no-charge counter (AFTA evidence)
      operationId: getNoChargeStats
      description: Aggregate count of paid calls that were waived under AFTA guarantees (5xx, breaker, schema fail, stale data).
      responses:
        '200':
          description: No-charge counter
          content:
            application/json:
              schema: { type: object }

  /api/receipt/verify:
    post:
      tags: [AFTA]
      summary: Verify an Ed25519-signed receipt
      operationId: postReceiptVerify
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [receipt]
              properties:
                receipt: { type: string, description: Receipt blob from a previous paid response }
      responses:
        '200':
          description: Verification result
          content:
            application/json:
              schema: { type: object, properties: { ok: { type: boolean }, valid: { type: boolean }, signed_at: { type: string } } }

  /api/preview/routing:
    get:
      tags: [Premium]
      summary: Public preview of premium model routing
      operationId: getRoutingPreview
      description: Free preview of the premium routing endpoint. Returns top-1 recommendation only. Use /api/premium/routing for ranked top-N with full reasoning.
      responses:
        '200':
          description: Recommended model id and one-line rationale.
          content:
            application/json:
              schema: { type: object }

  /api/premium/routing:
    get:
      tags: [Premium]
      summary: Ranked model routing recommendations
      operationId: getPremiumRouting
      security: [{ BearerAuth: [] }]
      parameters:
        - in: query
          name: prompt
          schema: { type: string }
        - in: query
          name: optimize
          schema: { type: string, enum: [cost, speed, quality, balanced] }
      responses:
        '200':
          description: Ranked top-N model recommendations with rationale and signed receipt.
          content:
            application/json:
              schema: { type: object }
        '402': { description: Insufficient credits or no token (x402-compatible) }

  /api/premium/news/search:
    get:
      tags: [Premium]
      summary: Full-text search across AI news archive
      operationId: getPremiumNewsSearch
      security: [{ BearerAuth: [] }]
      parameters:
        - in: query
          name: q
          required: true
          schema: { type: string }
        - in: query
          name: from
          schema: { type: string, format: date }
        - in: query
          name: to
          schema: { type: string, format: date }
        - in: query
          name: limit
          schema: { type: integer, default: 25, maximum: 100 }
      responses:
        '200':
          description: Matching articles, ranked.
          content:
            application/json:
              schema: { type: object }

  /api/premium/cost/projection:
    get:
      tags: [Premium]
      summary: Compute monthly cost across model candidates
      operationId: getPremiumCostProjection
      security: [{ BearerAuth: [] }]
      parameters:
        - in: query
          name: model
          required: true
          schema: { type: string, example: 'opus-4-7,gpt-5-5' }
        - in: query
          name: input_tokens_per_day
          schema: { type: integer }
        - in: query
          name: output_tokens_per_day
          schema: { type: integer }
        - in: query
          name: horizon
          schema: { type: string, enum: [daily, monthly, yearly], default: monthly }
      responses:
        '200':
          description: Projected cost per model.
          content:
            application/json:
              schema: { type: object }

  /api/premium/whats-new:
    get:
      tags: [Premium]
      summary: Aggregated daily delta across the whole TensorFeed dataset
      operationId: getPremiumWhatsNew
      security: [{ BearerAuth: [] }]
      parameters:
        - in: query
          name: days
          schema: { type: integer, default: 1, minimum: 1, maximum: 7 }
        - in: query
          name: news_limit
          schema: { type: integer, default: 10, maximum: 50 }
      responses:
        '200':
          description: New models, new pricing, new status incidents, top news.
          content:
            application/json:
              schema: { type: object }

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: tf_live_*
      description: |
        Bearer token from POST /api/payment/confirm. Required for premium endpoints. Each call decrements credits.
        On insufficient credits, the server returns HTTP 402 Payment Required with a body that points to /api/payment/buy-credits (x402-compatible).

  schemas:
    NewsArticle:
      type: object
      required: [id, title, url]
      properties:
        id: { type: string }
        title: { type: string }
        url: { type: string, format: uri }
        source: { type: string }
        sourceDomain: { type: string }
        snippet: { type: string }
        categories: { type: array, items: { type: string } }
        publishedAt: { type: string, format: date-time }
        fetchedAt: { type: string, format: date-time }

    StatusService:
      type: object
      required: [name, status]
      properties:
        name: { type: string }
        provider: { type: string }
        status: { type: string, enum: [operational, degraded, partial_outage, major_outage, maintenance, unknown] }
        components:
          type: array
          items:
            type: object
            properties:
              name: { type: string }
              status: { type: string }
        lastChecked: { type: string, format: date-time }

externalDocs:
  description: Full developer documentation, SDKs, machine-readable manifests, and the daily Hugging Face dataset mirror
  url: https://tensorfeed.ai/developers

x-tensorfeed:
  hugging_face_dataset:
    repo: tensorfeed/ai-ecosystem-daily
    url: https://huggingface.co/datasets/tensorfeed/ai-ecosystem-daily
    description: Daily JSONL snapshots of the entire public API. Inference-only license.
    cadence: daily at 08:00 UTC
