{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://api.quanor.com/api/docs/stream/feed_stream.v1.schema.json","$comment":"The feed stream's messages, version 1, besides the frames of feed_frame.v1.schema.json. This file has no root schema: validate a message a client sends against #/$defs/client, and a control message the stream sends against #/$defs/control (a frame against feed_frame.v1.schema.json's root). Every object admits fields it does not name, but a selection. A field the stream sets that names a kind, a state, a reason or a code (status.builder) lists the values version 1 names and admits any other string. A message whose type version 1 names neither here nor in feed_frame.v1.schema.json is valid (unknown_message), to be ignored; one whose type it names is held to that type's schema. What a client sends stays closed.","title":"A feed stream message","$defs":{"client":{"oneOf":[{"$ref":"#/$defs/subscribe"},{"$ref":"#/$defs/selection_message"},{"$ref":"#/$defs/ping"},{"$ref":"#/$defs/pong"}]},"control":{"oneOf":[{"$ref":"#/$defs/ready"},{"$ref":"#/$defs/selection_ack"},{"$ref":"#/$defs/through"},{"$ref":"#/$defs/catch_up"},{"$ref":"#/$defs/resync"},{"$ref":"#/$defs/access_changed"},{"$ref":"#/$defs/status"},{"$ref":"#/$defs/refetch"},{"$ref":"#/$defs/reconnect"},{"$ref":"#/$defs/ping"},{"$ref":"#/$defs/pong"},{"$ref":"#/$defs/unknown_message"}]},"selection":{"description":"A selection says what one mirror asks the feed for. Every field may be left out, and a field this version does not know is refused (4400 on the stream, 422 on /v1), never ignored.","type":"object","additionalProperties":false,"properties":{"companies":{"type":"array","items":{"type":"integer","minimum":1,"maximum":2147483647},"minItems":1,"maxItems":2000,"description":"Only these companies (with watchlist, these and the reader's watchlist); leave both out for every company."},"watchlist":{"type":"boolean","description":"Also the app reader's watchlist. A key has none: its selection with watchlist and no companies selects nothing."},"markets":{"type":"array","items":{"type":"integer","minimum":1,"maximum":2147483647},"minItems":1,"maxItems":64,"description":"Only companies on these markets (market_exchange_id)."},"item_kinds":{"type":"array","minItems":1,"items":{"enum":["announcement","market_alert","earnings_call","pre_earnings_analysis","overview_audio","insider_transaction"]},"description":"Leave out for every kind but overview_audio and insider_transaction. An API key is sent announcements and pre-earnings analyses alone."},"part_kinds":{"type":"array","minItems":1,"items":{"enum":["flash","story"]},"description":"Only announcements with one of these parts. An API key may name flash."},"teasers":{"type":"boolean","description":"Also send the items of companies outside the key's allowed_company_ids, as teasers."}}},"cursor":{"type":"string","pattern":"^[1-9][0-9]{0,9}\\.(0|[1-9][0-9]{0,18})$","description":"A feed cursor, <epoch>.<seq>, seq at most 9223372036854775807. Two cursors order by epoch, then by seq, each as an integer: 1.9 is before 1.10."},"subscribe":{"type":"object","required":["type","v","since","lang","selections"],"properties":{"type":{"const":"subscribe"},"v":{"const":1},"since":{"anyOf":[{"$ref":"#/$defs/cursor"},{"type":"null"}]},"lang":{"enum":["en","sv"],"description":"The served language: en or sv. The stream does not refuse another, and serves it English; GET /v1/feed refuses one (422)."},"selections":{"type":"object","maxProperties":8,"propertyNames":{"minLength":1,"maxLength":128,"description":"A mirror id: at most 128 bytes in UTF-8 (limits.mirror_id_bytes). maxLength counts characters, so an id beyond ASCII holds fewer."},"additionalProperties":{"$ref":"#/$defs/selection"}}}},"selection_message":{"type":"object","required":["type","mirror_id","selection"],"properties":{"type":{"const":"selection"},"mirror_id":{"type":"string","minLength":1,"maxLength":128,"description":"At most 128 bytes in UTF-8 (limits.mirror_id_bytes). maxLength counts characters, so an id beyond ASCII holds fewer."},"selection":{"anyOf":[{"$ref":"#/$defs/selection"},{"type":"null"}]}}},"ping":{"description":"t is a JSON number. The stream's is its clock in ms since the epoch; a client's is the client's to choose and comes back in the pong, and a ping whose t is anything else is refused (4400).","type":"object","required":["type","t"],"properties":{"type":{"const":"ping"},"t":{"type":"number"}}},"pong":{"description":"The answer to a ping, with its t. The stream reads no t of a client's pong.","type":"object","required":["type"],"properties":{"type":{"const":"pong"},"t":{"type":"number"}}},"ready":{"type":"object","required":["type","cursor","access_version","server_time","processing","n"],"properties":{"type":{"const":"ready"},"v":{"const":1,"description":"The protocol version the stream speaks on this socket."},"cursor":{"$ref":"#/$defs/cursor"},"access_version":{"type":"string"},"lang":{"type":"string","description":"The language served (en or sv): the one the access was resolved in, en for a language the feed is not written in."},"ping_interval_ms":{"type":"integer","minimum":1,"description":"How often the stream pings this socket, in milliseconds."},"server_time":{"$ref":"feed_frame.v1.schema.json#/$defs/moment"},"processing":{"type":"array","items":{"$ref":"feed_frame.v1.schema.json#/$defs/processing"},"description":"The rows pending at connect, each with m (with can_pending)."},"processing_complete":{"type":"boolean"},"n":{"type":"integer","minimum":1,"description":"This connection's counter, contiguous: an integer of up to 64 bits."}}},"selection_ack":{"type":"object","required":["type","mirror_id","n"],"properties":{"type":{"const":"selection_ack"},"mirror_id":{"type":"string"},"cursor":{"$ref":"#/$defs/cursor","description":"The highest position the stream had heard as it acknowledged, at or above the cursor its frames carry: a read of the mirror alone, issued after the ack from its window's through, reads at least to it. Absent only before the stream has heard a head."},"n":{"type":"integer","minimum":1,"description":"This connection's counter, contiguous: an integer of up to 64 bits."}}},"through":{"type":"object","required":["type","cursor","n"],"properties":{"type":{"const":"through"},"cursor":{"$ref":"#/$defs/cursor"},"n":{"type":"integer","minimum":1,"description":"This connection's counter, contiguous: an integer of up to 64 bits."}}},"catch_up":{"type":"object","required":["type","through","n"],"properties":{"type":{"const":"catch_up"},"through":{"$ref":"#/$defs/cursor"},"n":{"type":"integer","minimum":1,"description":"This connection's counter, contiguous: an integer of up to 64 bits."}}},"resync":{"type":"object","required":["type","n"],"properties":{"type":{"const":"resync"},"n":{"type":"integer","minimum":1,"description":"This connection's counter, contiguous: an integer of up to 64 bits."}}},"access_changed":{"type":"object","required":["type","access_version","n"],"properties":{"type":{"const":"access_changed"},"access_version":{"type":"string"},"n":{"type":"integer","minimum":1,"description":"This connection's counter, contiguous: an integer of up to 64 bits."}}},"status":{"type":"object","required":["type","builder","n"],"properties":{"type":{"const":"status"},"builder":{"description":"The values version 1 names; a client reads one it does not know as unknown.","anyOf":[{"enum":["live","silent"]},{"type":"string"}]},"n":{"type":"integer","minimum":1,"description":"This connection's counter, contiguous: an integer of up to 64 bits."}}},"refetch":{"type":"object","required":["type","feed_item_id","n"],"properties":{"type":{"const":"refetch"},"feed_item_id":{"type":"string"},"n":{"type":"integer","minimum":1,"description":"This connection's counter, contiguous: an integer of up to 64 bits."}}},"reconnect":{"type":"object","required":["type","reconnect_after_ms","n"],"properties":{"type":{"const":"reconnect"},"reconnect_after_ms":{"type":"integer","minimum":0,"maximum":5000,"description":"The wait the stream suggests before reconnecting: at most limits.reconnect_after_ms_max in feed_stream.v1.json."},"n":{"type":"integer","minimum":1,"description":"This connection's counter, contiguous: an integer of up to 64 bits."}}},"unknown_message":{"description":"A message of a type version 1 does not name: ignore it. Its type is none of the stream's messages', either way, or the frames' (feed_frame.v1.schema.json), so a message of a named type that does not hold to that type's schema is invalid rather than unknown.","type":"object","required":["type"],"properties":{"type":{"type":"string","not":{"enum":["item","part","hidden","withdrawn","processing","processing_resolved","ready","selection_ack","through","catch_up","resync","access_changed","status","refetch","reconnect","ping","pong","subscribe","selection"]}}}}}}