{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/classifier-dev/json-schema/classifier-dev-single-result-schema.json",
  "title": "SingleResult",
  "x-generated": "2026-10-29",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/classifier-dev-openapi.json#/components/schemas/SingleResult",
  "type": "object",
  "properties": {
    "usage": {
      "$ref": "#/$defs/TokenUsage"
    },
    "pricing": {
      "$ref": "#/$defs/ClassificationPricing"
    },
    "article": {
      "type": "object",
      "properties": {
        "url": {
          "type": "string"
        },
        "title": {
          "type": "string"
        },
        "markdown": {
          "type": "string"
        },
        "html": {
          "type": "string"
        }
      }
    },
    "label": {
      "type": "string"
    },
    "confidence": {
      "type": [
        "number",
        "null"
      ],
      "description": "0 to 1, calibrated: how likely the chosen label is right among your labels. Measured on six-way emotion, answers >= 0.9 were right 82% of the time and answers < 0.5 were right 29%. It is not a fit score — text matching none of your categories still gets one; add a label such as 'none of these' for that. Null when the provider returns no score or the smart tier replaces the scored answer."
    },
    "scores": {
      "type": [
        "object",
        "null"
      ],
      "additionalProperties": {
        "type": "number"
      },
      "description": "Model preference per supplied label. Sums to 1 for single-label; independent per label for multi-label. Does not validate the input or guarantee correctness."
    },
    "escalated": {
      "type": "boolean",
      "description": "Present and true on the smart tier when the answer was re-asked of the reasoning model; confidence and scores are null because the reasoning model does not return comparable probabilities."
    },
    "unscored": {
      "type": "string",
      "description": "Explains why confidence and scores are unavailable, such as smart escalation without comparable probabilities. Route to review when a numeric confidence is required."
    },
    "labels": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "With ?multi=1 only: every label scoring >= 0.7, most likely first. `label` is then the first of them, or empty, and confidence is null."
    },
    "ms": {
      "type": "integer"
    },
    "tier": {
      "type": "string"
    },
    "model": {
      "type": "string"
    }
  },
  "$defs": {
    "ClassificationPricing": {
      "type": "object",
      "description": "USD customer pricing, separate from upstream provider spend. total_usd is zero for unbilled requests, null when unknown, and before credit rounding. Pending settlement is not a receipt. Ordinary pricing.input_tokens includes billable primary calls; Jev long context uses original cl100k_base context tokens summed once across inputs at $0.084/M, independent of dimensions and actual screening/final usage. Plain-text responses and TypeSafe-compatible responses retain their existing shapes.",
      "properties": {
        "scrape_requests": {
          "type": "integer",
          "minimum": 0,
          "maximum": 1
        },
        "usd_per_scrape": {
          "type": "number",
          "const": 0.0022
        },
        "scrape_usd": {
          "type": "number",
          "description": "Retained scrape charge, including on errors after a billed or uncertain provider attempt."
        },
        "classification_usd": {
          "type": [
            "number",
            "null"
          ]
        },
        "currency": {
          "const": "USD"
        },
        "rate_version": {
          "type": "string"
        },
        "basis": {
          "type": "string",
          "const": "original_context_tokens",
          "description": "Present for Jev long context."
        },
        "tokenizer": {
          "type": "string",
          "const": "cl100k_base",
          "description": "Present for Jev long-context billing."
        },
        "billing_status": {
          "enum": [
            "not_billed",
            "pending",
            "settled",
            "review"
          ]
        },
        "total_usd": {
          "type": [
            "number",
            "null"
          ]
        },
        "estimated_usd": {
          "type": [
            "number",
            "null"
          ],
          "description": "Published classification price before free access or settlement; not an additional charge."
        },
        "input_tokens": {
          "type": [
            "integer",
            "null"
          ]
        },
        "escalations": {
          "type": "integer"
        },
        "input_usd_per_million": {
          "type": "number"
        },
        "usd_per_escalation": {
          "type": "number"
        },
        "models": {
          "type": "array",
          "description": "Legacy token-billed workspaces: the applied rate per provider/model, instead of the input-plus-escalation tariff.",
          "items": {
            "type": "object",
            "properties": {
              "provider": {
                "type": "string"
              },
              "model": {
                "type": "string"
              },
              "input_usd_per_million": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "output_usd_per_million": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "cached_input_usd_per_million": {
                "type": [
                  "number",
                  "null"
                ]
              }
            }
          }
        }
      }
    },
    "LongContextUsage": {
      "type": "object",
      "description": "Jev long-context processing totals. Documents/context tokens count original inputs once; chunk and selection counts and phase usage accumulate across dimension passes, not necessarily unique passages. Calls count answered provider calls, not attempts. Unknown provider token counts remain null. When every original plus its rubric and labels fits the provider budget, all originals reach final Jev in full, counted by full_input_passes. Otherwise every input is screened and final Jev sees selected evidence; eligible whole chunks may be omitted when the final context budget fills. No guarantee of universal accuracy.",
      "properties": {
        "context_tokens": {
          "type": "integer",
          "minimum": 0,
          "description": "Original input cl100k_base tokens summed once across inputs, independent of dimensions. Retail basis at $0.084/M, not actual screening/final usage."
        },
        "documents": {
          "type": "integer",
          "minimum": 0
        },
        "chunks": {
          "type": "integer",
          "minimum": 0
        },
        "screened_chunks": {
          "type": "integer",
          "minimum": 0
        },
        "eligible_chunks": {
          "type": "integer",
          "minimum": 0,
          "description": "Relevant or uncertain chunks eligible for final classification, including opposing evidence and exceptions."
        },
        "selected_chunks": {
          "type": "integer",
          "minimum": 0
        },
        "omitted_chunks": {
          "type": "integer",
          "minimum": 0,
          "description": "Eligible chunks omitted from final evidence due to context limits."
        },
        "full_input_passes": {
          "type": "integer",
          "minimum": 0,
          "description": "Successful final passes over complete originals when every input in the batch fits the Jev wire budget including rubric and labels. Counts document × dimension passes; these passes skip screening and omit no text. Original-context pricing is unchanged."
        },
        "screening_input_tokens": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 0
        },
        "final_input_tokens": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 0
        },
        "screening_calls": {
          "type": "integer",
          "minimum": 0
        },
        "final_calls": {
          "type": "integer",
          "minimum": 0
        },
        "screening_ms": {
          "type": "number",
          "minimum": 0
        },
        "final_ms": {
          "type": "number",
          "minimum": 0
        },
        "tokenizer": {
          "type": "string",
          "const": "cl100k_base"
        }
      }
    },
    "TokenUsage": {
      "type": "object",
      "properties": {
        "long_context": {
          "$ref": "#/$defs/LongContextUsage"
        },
        "input_tokens": {
          "type": [
            "integer",
            "null"
          ],
          "description": "Provider-reported input tokens across all answered calls, including smart escalation. Null if any count is unavailable."
        },
        "output_tokens": {
          "type": [
            "integer",
            "null"
          ]
        },
        "total_tokens": {
          "type": [
            "integer",
            "null"
          ],
          "description": "Input plus output; null if either is unknown."
        },
        "cached_input_tokens": {
          "type": [
            "integer",
            "null"
          ],
          "description": "Subset of input tokens, never added again to total_tokens."
        },
        "models": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "provider": {
                "type": "string"
              },
              "model": {
                "type": "string"
              },
              "calls": {
                "type": "integer"
              },
              "input_tokens": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "output_tokens": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "cached_input_tokens": {
                "type": [
                  "integer",
                  "null"
                ]
              }
            }
          }
        }
      }
    }
  }
}