{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/factiq-com/json-schema/factiq-com-media-request-schema.json",
  "title": "MediaRequest",
  "x-generated": "2026-11-07",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/factiq-com-openapi.json#/components/schemas/MediaRequest",
  "properties": {
    "query": {
      "type": "string",
      "title": "Query",
      "description": "Lexical search text: one to three key words, for example 'rate cuts' or 'export controls'. A returned row must contain most of the query words, so a long question returns fewer rows; after common words are dropped, the first eight words find rows and every word counts in the ranking. Put a phrase in double quotes to find it word for word: claims whose quote holds the phrase come first. Put the speaker in person and the publisher in institution instead of in the query. No serving-time model interprets the query. Retry synonyms or the speaker's own terminology if needed. Ignored by coverage; appearances matches only video title/channel metadata.",
      "default": ""
    },
    "search_target": {
      "type": "string",
      "enum": [
        "search",
        "claims",
        "passages",
        "pressure_points",
        "appearances",
        "coverage",
        "all",
        "videos",
        "companies",
        "episodes"
      ],
      "title": "Search Target",
      "description": "Canonical targets: \"search\" (default blended claims + passages), \"claims\" (normalized decision-relevant claims), \"passages\" (broad substantive paraphrase cards), \"pressure_points\" (refusals and declined-to-confirm claims), \"appearances\" (video catalog), and \"coverage\" (company-level structured-corpus inventory), and \"episodes\" (every episode the podcast feeds listed, transcribed or not, with title, date, link and the reason it was not transcribed; no paraphrase, no quote). Compatibility aliases are \"all\" -> \"search\", \"videos\" -> \"appearances\", and \"companies\" -> \"coverage\"; new callers should use the canonical values.",
      "default": "search"
    },
    "company": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Company",
      "description": "Comma-separated tickers and company names, mixed freely (for example, 'NVDA,OpenAI' or 'Federal Reserve,Alphabet'). A value that is a stored ticker matches the appearance's company or a section subject with that ticker. Any other value is read as the name of a company, institution, or organisation the podcast section is about, so unlisted companies (OpenAI, MiniMax, Manycore Tech), central banks, and regulators are found by name. Names are matched after dropping punctuation, a leading 'The', and corporate suffixes ('NVIDIA Corp.' finds NVIDIA; 'Alphabet' also reaches GOOGL rows), and each result records how every value was read: company_tickers, company_names, company_matched, and company_unmatched (with up to five possible matches per value that matched nothing). The appearances and coverage targets also match every value, upper-cased, against the entity references of claims (products, rivals, partners such as 'CUDA' or 'ChatGPT'); a value found only there is listed under company_references. Alternate spellings can return different appearances or coverage rows because reference names are matched exactly ('open ai' and 'OpenAI' select the same subject but not the same references); the claims rows are the same."
    },
    "company_filter": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Company Filter",
      "description": "Old name of company. Accepted with the same behaviour; the response note asks the client to update its plugin. Do not pass both."
    },
    "person": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Person",
      "description": "Case-insensitive name substring. Returns statements whose speaker matches, by the stored label or by the name the result shows for it (a label NADELLA shown as Satya Nadella). Only when no such statement matches does it return rows of episodes whose host or guest list holds the name; a note then says that the speaker of those rows can be someone else."
    },
    "sort": {
      "type": "string",
      "enum": [
        "relevance",
        "newest"
      ],
      "title": "Sort",
      "description": "\"relevance\" orders lexical score first and publication date second; a relevance search of claims with a query groups its rows by episode and gives them in turns (see episode_ranking). \"newest\" orders publication date first and lexical score second. Coverage uses its fixed company-inventory ordering.",
      "default": "relevance"
    },
    "appearance_type": {
      "anyOf": [
        {
          "type": "string",
          "enum": [
            "podcast",
            "tv_interview",
            "conference",
            "other",
            "speech",
            "testimony",
            "minutes",
            "statement",
            "press_conference",
            "hearing"
          ]
        },
        {
          "type": "null"
        }
      ],
      "title": "Appearance Type",
      "description": "Optional appearance-type filter. Interviews: podcast, tv_interview, conference, other. Official documents: speech, testimony, minutes, statement, press_conference, hearing. Applies to every canonical target."
    },
    "institution": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Institution",
      "description": "Case-insensitive substring of the institution that published an official document, for example 'Federal Reserve'. Returns official-document rows only; podcast and YouTube rows have no institution. Combine with show or channel to also include podcast or YouTube rows that match those; rows matching any given name filter are returned."
    },
    "country": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Country",
      "description": "ISO country code of the institution that published an official document, for example 'US'. Restricts every target to official documents of that country."
    },
    "show": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Show",
      "description": "Case-insensitive substring of a podcast show name, for example 'Odd Lots'. Returns podcast rows only: the show's feed episodes and its YouTube uploads when its YouTube channel is registered for it. With search_target='episodes' it names the show whose feed episodes are listed. Combine with channel or institution to also include YouTube or official-document rows that match those; rows matching any given name filter are returned."
    },
    "channel": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Channel",
      "description": "Case-insensitive substring of a YouTube channel name, for example 'Bloomberg Television'. Returns YouTube rows only. Combine with show or institution to also include podcast or official-document rows that match those; rows matching any given name filter are returned."
    },
    "claim_family": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Claim Family",
      "description": "Optional claim-ontology code. Blended search then returns structured claims only; appearances/coverage require matching claims. It is incompatible with search_target='passages'. Invalid codes return the valid vocabulary."
    },
    "date_from": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Date From",
      "description": "Inclusive YYYY-MM-DD lower bound on the video's stored publication/upload date, which may differ from its recording or event date."
    },
    "date_to": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Date To",
      "description": "Inclusive YYYY-MM-DD upper bound on the video's stored publication/upload date, which may differ from its recording or event date."
    },
    "detail": {
      "type": "boolean",
      "title": "Detail",
      "description": "For search/claims/passages/pressure_points, add normalized claim and company-attribution fields. Internal audit flags use bounded public names and include field_semantics; raw transcript text and evidence spans remain excluded. Has no effect on appearances or coverage rows.",
      "default": false
    },
    "limit": {
      "type": "integer",
      "maximum": 50.0,
      "minimum": 1.0,
      "title": "Limit",
      "description": "Maximum rows returned in one page, from 1 through 50. Use offset to read the pages after the first.",
      "default": 15
    },
    "offset": {
      "type": "integer",
      "minimum": 0.0,
      "title": "Offset",
      "description": "Number of ranked rows to skip before the returned page, so offset=15 with limit=15 gives rows 16 through 30 of the same ranking. Every result reports has_more, and adds next_offset when more rows follow; repeat the call with that value to read the next page.",
      "default": 0
    }
  },
  "type": "object"
}