Signals API
The Signals API gives read access to a fixed sample of output from Qriton Signals. It is meant for evaluating the format and the kind of evidence the service produces. It is not live data and is not a monitoring service; private monitoring with your own sources is arranged by contract.
GET /v1/signals/days
List the days of the sample.
Returns the daily records of the sample period, one item per day, in order of date. Each day gives post counts, the verification of its record and the number of candidate groups that day.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
from | query | string | First day to include (YYYY-MM-DD). |
to | query | string | Last day to include (YYYY-MM-DD). |
page | query | integer | Page number, from 1. |
page_size | query | integer | Items per page. |
Responses
| 200 | A page of days. |
| 400 | Invalid query. Codes: invalid_parameter, unknown_parameter, invalid_range, request_too_long. |
| 405 | Method other than GET. Codes: method_not_allowed. |
| 500 | Unexpected failure. Codes: internal_error. |
Example request
curl -X GET "https://api.qriton.com/v1/signals/days" \
-H "Authorization: Bearer $QRITON_API_KEY"
Example response
{
"sample": {
"version": "2026-10.1",
"period": {
"from": "2026-10-01",
"to": "2026-10-31"
},
"built_at": "2026-11-14T20:36:50.144Z",
"digest": "daa2ea63f98e47f0f7dd649f86960185cd8c34343fd5d3e2dedac4060ab690f2"
},
"notice": "This is sample data for October 2026 from one platform's public Romanian-language political content. A candidate group is not a finding of coordination: it is a lead that needs review by a person. The accuracy of the monitor has not been measured.",
"filters": {
"from": "2026-10-01",
"to": "2026-10-31"
},
"page": 1,
"page_size": 2,
"total": 31,
"total_pages": 16,
"items": [
{
"date": "2026-10-01",
"record_ref": "RO-TT-2026-10-01-001",
"record": {
"status": "verified",
"seal": "digest_only",
"verification_report_sha256": "dcdfc4687d9cbd40a10baddac124435bf6144776ad00e35f1fe3251c11f76741"
},
"posts": {
"collected": 197,
"analysed": 137
},
"accounts_with_posts": 38,
"candidate_groups": 0,
"record_sha256": "f3006486949a73d6e29a0a203343a2af9c32f8d53a0e5414882af63a16fc20b0"
},
{
"date": "2026-10-02",
"record_ref": "RO-TT-2026-10-02-001",
"record": {
"status": "verified",
"seal": "digest_only",
"verification_report_sha256": "7d0f97a0dc59814154925fd8cd298813cff9f4c16afb56b755ffed40138217da"
},
"posts": {
"collected": 164,
"analysed": 119
},
"accounts_with_posts": 38,
"candidate_groups": 0,
"record_sha256": "b8cbe827d7eb8e687afb645733ac2441c07690a7135af515613050d9f73e94b2"
}
]
}
GET /v1/signals/days/{date}
Get one day of the sample.
Returns the record of one day of the sample period.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
date required | path | string | The day (YYYY-MM-DD). |
Responses
| 200 | The day. |
| 400 | Malformed date. Codes: invalid_parameter, unknown_parameter. |
| 404 | No record for the day. Codes: day_not_found, not_found. |
| 405 | Method other than GET. Codes: method_not_allowed. |
| 500 | Unexpected failure. Codes: internal_error. |
Example request
curl -X GET "https://api.qriton.com/v1/signals/days/{date}" \
-H "Authorization: Bearer $QRITON_API_KEY"
Example response
{
"sample": {
"version": "2026-10.1",
"period": {
"from": "2026-10-01",
"to": "2026-10-31"
},
"built_at": "2026-11-14T20:36:50.144Z",
"digest": "daa2ea63f98e47f0f7dd649f86960185cd8c34343fd5d3e2dedac4060ab690f2"
},
"notice": "This is sample data for October 2026 from one platform's public Romanian-language political content. A candidate group is not a finding of coordination: it is a lead that needs review by a person. The accuracy of the monitor has not been measured.",
"day": {
"date": "2026-10-01",
"record_ref": "RO-TT-2026-10-01-001",
"record": {
"status": "verified",
"seal": "digest_only",
"verification_report_sha256": "dcdfc4687d9cbd40a10baddac124435bf6144776ad00e35f1fe3251c11f76741"
},
"posts": {
"collected": 197,
"analysed": 137
},
"accounts_with_posts": 38,
"candidate_groups": 0,
"record_sha256": "f3006486949a73d6e29a0a203343a2af9c32f8d53a0e5414882af63a16fc20b0"
}
}
GET /v1/signals/groups
List candidate groups.
Returns candidate groups: sets of posts that may show the same clip, formed by the daily comparison of clips, and sets of accounts connected by links in a weekly map. Each group states the basis of its links. A group is a lead for review by a person, not a finding of coordination; no group in the sample was reviewed.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
from | query | string | Include groups whose last member was seen on or after this day. |
to | query | string | Include groups whose first member was seen on or before this day. |
min_size | query | integer | Minimum number of members. |
basis | query | string: "identical_media", "same_sound_and_duration", "same_duration_within_window", "shared_sound", "shared_hashtag", "co_narrative" | Only groups with at least one link of this kind. |
kind | query | string: "linked_accounts", "possible_same_clip" | Only groups of this kind. |
page | query | integer | Page number, from 1. |
page_size | query | integer | Items per page, at most 100. |
Responses
| 200 | A page of groups. |
| 400 | Invalid query. Codes: invalid_parameter, unknown_parameter, invalid_range, request_too_long. |
| 405 | Method other than GET. Codes: method_not_allowed. |
| 500 | Unexpected failure. Codes: internal_error. |
Example request
curl -X GET "https://api.qriton.com/v1/signals/groups" \
-H "Authorization: Bearer $QRITON_API_KEY"
Example response
{
"sample": {
"version": "2026-10.1",
"period": {
"from": "2026-10-01",
"to": "2026-10-31"
},
"built_at": "2026-11-14T20:36:50.144Z",
"digest": "daa2ea63f98e47f0f7dd649f86960185cd8c34343fd5d3e2dedac4060ab690f2"
},
"notice": "This is sample data for October 2026 from one platform's public Romanian-language political content. A candidate group is not a finding of coordination: it is a lead that needs review by a person. The accuracy of the monitor has not been measured.",
"filters": {
"from": null,
"to": null,
"min_size": 2,
"basis": "co_narrative",
"kind": null
},
"page": 1,
"page_size": 1,
"total": 2,
"total_pages": 2,
"items": [
{
"id": "grp_9fd129741813397ebc73a165",
"kind": "linked_accounts",
"formed_by": "weekly_map",
"period": {
"from": "2026-10-19",
"to": "2026-10-25"
},
"first_seen": "2026-10-19",
"last_seen": "2026-10-25",
"size": 38,
"member_type": "account",
"accounts": 38,
"posts": 899,
"cross_account": true,
"linked_pairs": 193,
"basis": [
{
"code": "co_narrative",
"label": "The same narrative group in the daily synthesis. Narrative groups are written by an automated language model and were not reviewed by a person.",
"rule": "model_assigned",
"strength": null,
"links": 203
},
{
"code": "same_duration_within_window",
"label": "Posts with their original sound and the same uncommon length, by different accounts, inside the time window. Length alone can coincide.",
"rule": "fixed_rule",
"strength": null,
"links": 87
},
{
"code": "shared_hashtag",
"label": "The same rare hashtag.",
"rule": "fixed_rule",
"strength": null,
"links": 54
},
{
"code": "shared_sound",
"label": "The same sound that is not the original sound of the post.",
"rule": "fixed_rule",
"strength": null,
"links": 28
}
],
"strength": null,
"themes": [
{
"id": "electoral_party_mobilization",
"label": "Electoral, candidate, and party mobilization",
"posts": 311
},
{
"id": "russia_related_messaging",
"label": "Russia-related state, leader, or national messaging",
"posts": 219
},
{
"id": "war_military_security",
"label": "War, military, mobilization, and security",
"posts": 146
}
],
"clip": null,
"review": {
"status": "not_reviewed",
"is_finding": false,
"note": "No person has reviewed this group. It records what the posts or accounts have in common and is not a finding of coordination, common control, payment or intent."
},
"evidence": {
"source_file_sha256": "2c1c4a71df8728ef9c060db0b8d6fd9443100b9eba01c481cad866c75c05d973",
"members_commitment": "521995cce1ec6d1cb876ab6630b1c54f8895c2061dd498fc0f94c5b2f0675745"
},
"record_sha256": "d1abe3ca2dd760b59f994be1502790ee85b4ef77d8cf11dc7fa51f7a9f86d1a3"
}
]
}
GET /v1/signals/groups/{id}
Get one candidate group.
Returns one candidate group with the basis of its links, its review state and the digests for checking it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
id required | path | string | Group identifier. |
Responses
| 200 | The group. |
| 400 | Malformed identifier. Codes: invalid_parameter, unknown_parameter. |
| 404 | No such group. Codes: group_not_found, not_found. |
| 405 | Method other than GET. Codes: method_not_allowed. |
| 500 | Unexpected failure. Codes: internal_error. |
Example request
curl -X GET "https://api.qriton.com/v1/signals/groups/{id}" \
-H "Authorization: Bearer $QRITON_API_KEY"
Example response
{
"sample": {
"version": "2026-10.1",
"period": {
"from": "2026-10-01",
"to": "2026-10-31"
},
"built_at": "2026-11-14T20:36:50.144Z",
"digest": "daa2ea63f98e47f0f7dd649f86960185cd8c34343fd5d3e2dedac4060ab690f2"
},
"notice": "This is sample data for October 2026 from one platform's public Romanian-language political content. A candidate group is not a finding of coordination: it is a lead that needs review by a person. The accuracy of the monitor has not been measured.",
"group": {
"id": "grp_a60e482fc3cd368880da07fc",
"kind": "possible_same_clip",
"formed_by": "daily_clip_comparison",
"period": {
"from": "2026-10-16",
"to": "2026-10-16"
},
"comparison_day": "2026-10-16",
"first_seen": "2026-10-16",
"last_seen": "2026-10-16",
"size": 2,
"member_type": "post",
"accounts": 2,
"posts": 2,
"cross_account": true,
"linked_pairs": null,
"basis": [
{
"code": "same_sound_and_duration",
"label": "The same library sound and the same length, within a tolerance, published inside the time window.",
"rule": "fixed_rule",
"strength": "probable",
"links": null
}
],
"strength": "probable",
"themes": null,
"clip": {
"duration_seconds": [
285
],
"time_span_hours": 3.16,
"first_seen_known_for_posts": 2
},
"review": {
"status": "not_reviewed",
"is_finding": false,
"note": "No person has reviewed this group. It records what the posts or accounts have in common and is not a finding of coordination, common control, payment or intent."
},
"evidence": {
"source_file_sha256": "5c3532ca98566d44e9658c73121da65cc8e9e4534b20ee33228abbba90a4d686",
"verification_report_sha256": "ba6dff81f269cbbaddee3ff533c33a642a5397caa0b90167483f041bfc30ed91",
"members_commitment": "4df9d8c97b3a2af6ebe6062dbfdd9690769006f990dcb6aa592d829efbdcf002"
},
"record_sha256": "6d7398e43955f8ea031e8ccbb7c96cb3e2c530a484fe24977014f0cefaff4f4b"
}
}
GET /v1/signals/sample
Get the metadata of the sample.
Returns the period, the build time and the digest of the sample, what it covers, its totals, the weeks with a weekly map and their themes, and the meaning of every label. The digest is the SHA-256 of the canonical JSON of the sample file without its digest field.
Responses
| 200 | The sample metadata. |
| 400 | A parameter was given. Codes: unknown_parameter. |
| 405 | Method other than GET. Codes: method_not_allowed. |
| 500 | Unexpected failure. Codes: internal_error. |
Example request
curl -X GET "https://api.qriton.com/v1/signals/sample" \
-H "Authorization: Bearer $QRITON_API_KEY"
Example response
{
"sample": {
"schema_version": "qriton.signals.sample.v1",
"version": "2026-10.1",
"period": {
"from": "2026-10-01",
"to": "2026-10-31"
},
"built_at": "2026-11-14T20:36:50.144Z",
"digest": "daa2ea63f98e47f0f7dd649f86960185cd8c34343fd5d3e2dedac4060ab690f2",
"records_as_of": "2026-11-11",
"digest_algorithm": "sha256",
"digest_canonicalisation": "JSON with object keys sorted at every level, no whitespace, without the digest field"
},
"notice": "This is sample data for October 2026 from one platform's public Romanian-language political content. A candidate group is not a finding of coordination: it is a lead that needs review by a person. The accuracy of the monitor has not been measured.",
"coverage_statement": [
"The sample covers 1 October 2026 to 31 October 2026 and does not change. It is not live data.",
"It was built from outputs that the monitor already publishes: one platform (TikTok), public Romanian-language political content read without logging in, four scheduled runs a day at 00:00, 06:00, 12:00 and 18:00 UTC.",
"It contains daily counts, candidate groups and service figures. It contains no account names, no links to posts or profiles, no post identifiers and no captions or transcripts.",
"Candidate groups were formed by fixed rules, with one exception: the narrative-group link is assigned by an automated language model. No group was reviewed by a person, and none is a finding of coordination.",
"The accuracy of the monitor has not been measured. No figure in the sample is an accuracy, precision or recall figure."
],
"totals": {
"days": 31,
"days_with_record": 31,
"posts_collected": 4497,
"posts_analysed": 3530,
"candidate_groups": 5,
"candidate_groups_by_kind": {
"possible_same_clip": 3,
"linked_accounts": 2
}
},
"weeks": [
{
"week_start": "2026-10-19",
"week_end": "2026-10-25",
"days_in_sample_period": 7,
"days_with_record": 7,
"accounts": 45,
"posts": 913,
"linked_pairs": 193,
"account_groups": 1,
"accounts_without_link": 7,
"strict_links": {
"pairs": 50,
"largest_group_accounts": 27,
"groups": 1,
"accounts_linked": 27
},
"themes": [
{
"id": "electoral_party_mobilization",
"label": "Electoral, candidate, and party mobilization",
"posts": 313
},
{
"id": "russia_related_messaging",
"label": "Russia-related state, leader, or national messaging",
"posts": 220
},
{
"id": "war_military_security",
"label": "War, military, mobilization, and security",
"posts": 148
},
{
"id": "sovereignty_nationalism",
"label": "Sovereignty, nationalism, and patriotic identity",
"posts": 120
},
{
"id": "religion_history_identity",
"label": "Religion, history, and civilizational identity",
"posts": 116
},
{
"id": "protest_civic_mobilization",
"label": "Protest and civic mobilization",
"posts": 107
},
{
"id": "institutional_trust_corruption",
"label": "Institutional distrust, corruption, and alleged wrongdoing",
"posts": 95
},
{
"id": "gender_family_social_values",
"label": "Gender, family, and social-values framing",
"posts": 57
}
],
"weekly_map_sha256": "2c1c4a71df8728ef9c060db0b8d6fd9443100b9eba01c481cad866c75c05d973"
},
{
"week_start": "2026-10-26",
"week_end": "2026-11-01",
"days_in_sample_period": 6,
"days_with_record": 6,
"accounts": 44,
"posts": 749,
"linked_pairs": 204,
"account_groups": 1,
"accounts_without_link": 7,
"strict_links": {
"pairs": 43,
"largest_group_accounts": 23,
"groups": 2,
"accounts_linked": 26
},
"themes": [
{
"id": "electoral_party_mobilization",
"label": "Electoral, candidate, and party mobilization",
"posts": 307
},
{
"id": "russia_related_messaging",
"label": "Russia-related state, leader, or national messaging",
"posts": 204
},
{
"id": "sovereignty_nationalism",
"label": "Sovereignty, nationalism, and patriotic identity",
"posts": 146
},
{
"id": "protest_civic_mobilization",
"label": "Protest and civic mobilization",
"posts": 140
},
{
"id": "war_military_security",
"label": "War, military, mobilization, and security",
"posts": 126
},
{
"id": "religion_history_identity",
"label": "Religion, history, and civilizational identity",
"posts": 113
},
{
"id": "gender_family_social_values",
"label": "Gender, family, and social-values framing",
"posts": 78
},
{
"id": "institutional_trust_corruption",
"label": "Institutional distrust, corruption, and alleged wrongdoing",
"posts": 67
}
],
"weekly_map_sha256": "e667ded2e43d9fd99126d99244978510cb55f292868a5b5d0a58c4214ded5c42"
}
],
"labels": {
"basis": {
"identical_media": {
"label": "The archived files are byte-identical.",
"rule": "fixed_rule"
},
"same_sound_and_duration": {
"label": "The same library sound and the same length, within a tolerance, published inside the time window.",
"rule": "fixed_rule"
},
"same_duration_within_window": {
"label": "Posts with their original sound and the same uncommon length, by different accounts, inside the time window. Length alone