{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/hookdetector-com/json-schema/hookdetector-com-chat-in-schema.json",
  "title": "ChatIn",
  "x-generated": "2026-11-11",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/hookdetector-com-openapi.json#/components/schemas/ChatIn",
  "properties": {
    "message": {
      "type": "string",
      "maxLength": 4000,
      "minLength": 1,
      "title": "Message"
    },
    "conversation_id": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Conversation Id"
    },
    "language": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "maxLength": 60,
      "title": "Language",
      "description": "optional, up to 60 characters: only clips spoken or written in this language or dialect, in words or as a tag: \"Moroccan Darija\", \"ar-MA\", \"Egyptian Arabic\", \"Brazilian Portuguese\". Any language works, including a regional variety (\"Quebec French\", \"Flemish\", \"Catalan\") and a mixed, code-switched one (\"Hinglish\", \"Taglish\", \"Moroccan Darija with French\"), or two joined by \"or\" (\"Tagalog or Taglish\"). The value is handed to the judges exactly as written; how well they honour a mixed or either-of value is not measured yet. Saying it inside topic works too; this field wins when both are given. For chat, omitted or null keeps the conversation's current setting; a value sets it for this and later turns; the empty string clears it back to any language / any country."
    },
    "country": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "pattern": "^[A-Za-z]{2}$",
      "title": "Country",
      "description": "optional: only clips from creators in this country, as an assigned ISO 3166-1 alpha-2 code: MA, EG, BR, US (UK is read as GB). For a region that is not a country, send its country's code and name the regional variety in language: Quebec is country CA with language \"Quebec French\", Flanders BE with \"Flemish\", Catalonia ES with \"Catalan\". The country places the TikTok search there; the language judge does the regional filtering, and Instagram reports no country. A country alone does not restrict the language. For chat, omitted or null keeps the conversation's current setting; a value sets it for this and later turns; the empty string clears it back to any language / any country."
    },
    "posted_within_days": {
      "type": [
        "integer",
        "null"
      ],
      "enum": [
        7,
        30,
        90,
        365,
        0,
        null
      ],
      "title": "Posted Within Days",
      "description": "since 2026-10-01: optional, how recent the clips must be, as days: 7, 30, 90, 365. The search asks the platforms for that window and the floor for a clip under 7 days old uses views per day (10,000 a day passes); null or left out means any time. A clip's `posted_at` and `age_days` say what the run found. For chat (the recency chip): omitted keeps the conversation's current setting; 7, 30, 90 or 365 sets it for this and later turns and wins over a recency phrase in the message; an explicit null on REST, or 0 on either door, clears it back to any time."
    },
    "seed_hook_ids": {
      "items": {
        "type": "string",
        "format": "uuid"
      },
      "type": [
        "array",
        "null"
      ],
      "maxItems": 10,
      "uniqueItems": true,
      "title": "Seed Hook Ids",
      "description": "since 2026-10-01: optional, up to 10 hook ids from your runs (a kept hook from GET /v1/keeps, or any hook you can read): \"find more like these\". The engine reads their lines, topics, creators and languages to steer the search phrases and the creators it expands; a seed is never delivered again. An id that is not one of your hooks is 422."
    },
    "count": {
      "anyOf": [
        {
          "type": "integer",
          "maximum": 30.0,
          "minimum": 1.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Count",
      "description": "how many hooks a run this turn starts should deliver, 1 to 30; a size typed into the message (\"15 hooks\") wins over it, and it wins over the turn's own guess; null or omitted lets the turn decide. Fewer hooks is a faster, cheaper run"
    },
    "platforms": {
      "items": {
        "type": "string",
        "enum": [
          "tiktok",
          "instagram",
          "youtube"
        ]
      },
      "type": [
        "array",
        "null"
      ],
      "maxItems": 3,
      "minItems": 1,
      "uniqueItems": true,
      "title": "Platforms",
      "description": "since 2026-10-10: optional, which platforms to search and deliver from, a non-empty list of \"tiktok\", \"instagram\" and \"youtube\" (YouTube Shorts); left out (or all three) searches all three. [\"instagram\"] delivers Instagram reels only. Names are read without regard to case and a repeat counts once; an empty list or any other name is 422 naming platforms. The run echoes it as `platforms`."
    }
  },
  "type": "object",
  "required": [
    "message"
  ]
}