DCinside sends new candidates, engagement updates for all pending posts and removals. Surf returns waiting before queue entry plus 15 minutes, then refreshed scores for every eligible pending candidate each cycle. The rehearsal cadence is fixed at five minutes.
This endpoint reference describes the rehearsal proposal. Verify the deployed artifact, persistence, cadence and alert delivery against Rehearsal and acceptance before starting.
Stable request ID. The existing format is YYYYMMDDTHHMM in KST. Retry the same ID with the same body.
cycle_time
Scheduled five-minute boundary, with an explicit offset. Up to 60 seconds ahead of server time is accepted for clock tolerance.
candidates
All new candidates since the last acknowledged delivery, including posts that enter and leave between cycles; use source="unknown" when unavailable. After uncertain delivery, include them again in the next cycle. Identity is gall_id plus post_no; repeats retain original content and known queue-entry time and count once. No candidate-count cap.
engagement
Current readings for every pending candidate, including newly sent candidates. Unknown counters are null.
candidate_scores
Proposed mapping for available admin snapshots. The existing wire shape requires this array, but it may be empty. Review its fields with the delivered model.
removals
Stop scoring the listed posts. Under the operator-independent policy, send only deleted/aged_out removals promptly; saved/hidden labels remain client-side. DCinside applies the 24-hour age filter and sends engagement every cycle until removal. See the worker handoff.
published_windows
Complete last-20 actual published snapshots, independently for main and light. Received posts need only identity and placed_at; posts never delivered need one-time title/body/image metadata in the window entry and JPEGs through the image route. Missing/null means unknown; [] asserts an empty feed. See Event deduplication.
extracted_at means original entry into DCinside’s queue, including for posts delivered after an operator decision. Model 0924 first scores at or after extracted_at + 15 minutes. Before then, the result is waiting, with due_cycle set to the first five-minute boundary at or after that point. The target remains at least 99% first scored within two cycles after the 15-minute mark; reaching that target does not end retention. Saved/hidden decisions remain in that denominator; immediate deleted/aged_out removals before the mark retain the early-removal exclusion. A null entry time returns not_scored / missing_clock; a later retransmission can fill a previously unknown entry time, but cannot replace one already known.New rehearsal candidates must provide a non-null, RFC 3339 extracted_at. The field remains nullable on the API for compatibility and repair. A missing clock cannot establish scoring eligibility or prove the first-score SLA, and must not be silently removed from the 99% denominator; report and repair it. An early saved/hidden decision is not an exclusion under the new policy. The sending worker must validate queue-entry clocks before sending; the shared transport helper rejects missing or invalid candidate entry clocks.Pending posts keep being rescored after their first score and after 25 minutes; the API has no automatic 24-hour expiry. The client sends deleted/aged_out removals when its deletion or age condition is met. The API applies received removals before scoring that cycle, so a candidate and its removal sent together do not obtain a first score. Saved/hidden enum values remain accepted for compatibility and still remove the post if received. Resending any removed identity does not revive it, including after restart; backfilling previously removed posts requires a separately agreed re-entry policy.Use the field reference below for proposed types and examples. JSON may be plain or gzip-compressed. Current size and array protections are listed in Conventions; do not truncate the full queue to fit them.
The response contains post IDs, final scores, model and weight versions, scoring times and counts. Per-part predictions are optional. All raw score rows remain present, including same-event duplicates. After raw scoring, the API durably prepares the cycle’s scores and exact candidate/published-window evidence, then allows background checks to progress within the remaining response budget before freezing one final response. The separate deduplication report compares candidates only against that cycle’s supplied windows. For Main and Light independently, ranked contains all scored candidates except confirmed duplicates; unchecked is a diagnostic subset of ranked and does not exclude candidates. Facts completed during this bounded wait can therefore appear in the same cycle. A newer cycle cannot substitute its window or scores into an older response.Surf prioritizes the highest-scored work eligible to run. The wait ends when the prepared cycle’s still-needed comparisons have settled or its remaining wait budget expires; finding one usable candidate does not end the wait. Validated full-evidence unknowns and unavailable evidence can leave rows unchecked even when no further assessment is currently possible. Transient failures and incomplete evidence delivery remain retryable; a retry cooldown is not a completed check. A partial report includes unchecked candidates in ranked; only confirmed duplicates are excluded. Unchecked remains diagnostic, not proof of uniqueness. Missing content or a failed LLM check does not remove raw scores or certify those posts as unique.The latest client requirement allows 60 seconds from sending, including at most one retry. A late response is skipped for that cycle, but its data must still be reconciled. Recover using GET /v1/scores/{cycle_id} or replay the original request. See the worker integration notes for retry budgeting. The server’s default 25-second processing budget includes preparation, raw scoring, bounded waiting and finalization, with time reserved to persist the response. Waiting releases the database writer so background results can commit. Background inference can continue after the response; this budget does not promise that every comparison resolves or prove the client’s end-to-end deadline.New cycles may change scores and dedup decisions. Retries and GET for a completed cycle return its original response, including any partial/unavailable dedup result. Later images, a recovered provider, a background verdict or a different published snapshot do not rewrite that cycle. Send the next scheduled new cycle to receive an updated report; GET does not poll for newer verdicts. Changing a snapshot under an accepted cycle ID returns 409.If a request stops after preparation but before finalization, replaying the unchanged request resumes its prepared scores, counts and evidence without scoring or ingesting them again. GET returns 404 until a final result exists. For newly prepared cycles, scored_at records raw model score completion before the deduplication wait; it is not the final response time or client round-trip duration.counts.candidates and counts.removals count identities first accepted in that cycle, excluding repeats within or across requests. Removal counts describe receipt, not when an operator decided; saved/hidden labels remain a separate client-side series and no longer generate removal receipts under this policy. counts.scored_now counts scoring events in that cycle, including rescoring, not unique first scores. For daily reconciliation, join by post identity, group unique entrants by original extracted_at KST date, and track first scores separately from per-cycle scoring and removal receipt. Between-cycle entrants increase the unique entrant totals. Original queue-entry and delivered removal timestamps are retained after removal. Removals remain effective after restart or candidate retransmission.DCinside must record the actual policy switch time and cohort assignment. The proposed 2026-10-15 00:00 KST cycle 20261015T0000 is not confirmed; the earlier first-score-or-25-minute hold was never activated. Do not relabel historical measurements or infer a deployed policy period from a documentation update. Retrospective backfill of prior removals remains undecided. These API counters support reconciliation but do not calculate the first-score SLA denominator.Scores use engagement and admin observations available through cycle_time, and age features at that time. Retaining a post after an operator decision does not produce an as-of-decision score: report these comparisons separately from scores available before the decision. Hidden alone does not veto a client pick under the new policy. The client skips currently real-board posts and selects the next eligible candidate; intervention follows actual publication/unpublication. A post already present in a supplied tier window is excluded from that tier’s dedup ranking while its raw score remains in results. Those last-20 snapshots do not replace the client’s full current-board check.Examples illustrate the contract, not measured deployment results. Empty titles and unknown creation times can still be scored once queue-entry eligibility is known. Images may arrive later and do not delay scoring. DCinside applies the 24-hour queue filter and sends removals.
Proposed API key sent as the whole Authorization header value. One long-lived key, handed privately to the partner contact and rotated on either side's request. Per-endpoint scopes are not currently enforced.
Optional compression. Set to gzip only for a gzip-compressed body; plain JSON is also supported.
Available options:
gzip
Body
application/json
Proposed rehearsal wire shape. Required arrays and extra metadata need payload review. Current other-array and request-size protections are engineering limits, not client quotas.
Idempotency key: the cycle time in KST as YYYYMMDDTHHMM, for example 20260929T0205. The same id with the same body returns the stored response. The same id with a different body returns 409.
Scheduled five-minute rehearsal boundary with an explicit RFC 3339 offset; normalize to KST for cycle_id. Up to 60 seconds ahead of server time is allowed, inclusive. Runtime supports other configured intervals outside this rehearsal.
New posts since acknowledged delivery; re-include after uncertain timeout when GET finds no completed response. Identity gall_id/post_no is stored and counted once across repeated rows/cycles. Original content and known extracted_at remain unchanged. No candidate-count cap; the whole JSON body must fit within 16 MiB after decompression. Pending candidates remain until removed.
One row for every pending candidate, every cycle. Pending means sent in this or an earlier call and not yet in removals. The current 5,000-row cap is an engineering protection, not an agreed business quota; validate it against full-queue delivery.
Available admin snapshots, when present. Existing wire shape requires the array but permits []. Confirm feature mapping and requiredness with the client and delivered model. The current 5,000-row cap is an engineering protection, not an agreed business quota; validate it against full-queue delivery.
Saved, hidden, deleted or aged-out post identities. Re-inclusion within/across cycles is idempotent and counts only first accepted removals; candidate retransmission cannot revive a removed post.
Optional independent current last20 Main/Light published snapshots. Required for published-window dedup coverage; omission/null stays unknown, while [] asserts an empty feed. References reuse archived evidence. For never-delivered posts, bootstrap title/body/image metadata once here, with JPEGs uploaded separately; do not add them as pending candidates.
Show child attributes
Response
Complete raw scores and the immutable deduplication report for this cycle. Provider failure can return 200 with raw scores and explicit unavailable/unchecked deduplication.
Version reported by the actual loaded Model 0924 adapter and configured down-vote coefficient. No environment-only label override or proxy scorer is used.
One result per pending candidate under the proposed refresh policy. Scores may change across new cycles; replay of a completed cycle is unchanged. Removed posts are absent from subsequent cycles.
Persisted LLM same-event rankings and honest unchecked coverage for main/light. Every raw score remains in results. Omitted for legacy completed cycles. Partial/unavailable completed reports remain immutable on POST replay and GET.
Show child attributes
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"DCinside RTB API Documentation","colors":{"primary":"#000000","light":"#4D9CFF","dark":"#0050B4"},"api":{"playground":{"display":"simple","proxy":false}},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"surfai-5f1034e6","hasAudioNarration":false,"actualSubdomain":"surfai-5f1034e6","customDomains":["surf-dcinside-api.kr.ask.surf"],"gitSource":{"type":"github","owner":"hl219","repo":"dcinside-rtb-api-docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"entitlements":{"AI_CHAT":{"status":"DISABLED"},"WEB_MCP":{"status":"DISABLED"},"NARRATION":{"status":"DISABLED"}},"buildId":"6ace4f2a99d09ae5ef3fff07","clientVersion":"0.0.4117","searchFilterCounts":[{"language":"default","tag":"Getting Started","count":5},{"language":"default","tag":"Scoring API","count":4},{"language":"default","tag":"Weights and Outcomes","count":3},{"language":"default","tag":"Operations","count":1},{"language":"default","tag":"Images API","count":1}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"cycles","slug":"/cycles","pageMetadata":{"title":"Score a Cycle","description":"Proposed rehearsal cycle payload and score response","openapi":"openapi.json POST /v1/cycles","href":"/cycles"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Proposed rehearsal cycle payload and score response\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,p:`p`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,..._provideComponents(),...props.components},{Heading,Table,Warning}=_components;if(!Heading)_missingMdxReference(`Heading`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsx(Heading,{level:`2`,id:`proposed-rehearsal-behavior`,children:`Proposed rehearsal behavior`}),`\n`,_jsxs(_components.p,{children:[`DCinside sends new candidates, engagement updates for all pending posts and removals. Surf returns `,_jsx(_components.code,{children:`waiting`}),` before queue entry plus 15 minutes, then refreshed scores for every eligible pending candidate each cycle. The rehearsal cadence is fixed at five minutes.`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`This endpoint reference describes the rehearsal proposal. Verify the deployed artifact, persistence, cadence and alert delivery against `,_jsx(_components.a,{href:`/rollout#agreed-integration-and-remaining-readiness`,children:`Rehearsal and acceptance`}),` before starting.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`request-guidance`,children:`Request guidance`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Field`}),_jsx(_components.th,{children:`Meaning`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`cycle_id`})}),_jsxs(_components.td,{children:[`Stable request ID. The existing format is `,_jsx(_components.code,{children:`YYYYMMDDTHHMM`}),` in KST. Retry the same ID with the same body.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`cycle_time`})}),_jsx(_components.td,{children:`Scheduled five-minute boundary, with an explicit offset. Up to 60 seconds ahead of server time is accepted for clock tolerance.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`candidates`})}),_jsxs(_components.td,{children:[`All new candidates since the last acknowledged delivery, including posts that enter and leave between cycles; use `,_jsx(_components.code,{children:`source=\"unknown\"`}),` when unavailable. After uncertain delivery, include them again in the next cycle. Identity is `,_jsx(_components.code,{children:`gall_id`}),` plus `,_jsx(_components.code,{children:`post_no`}),`; repeats retain original content and known queue-entry time and count once. No candidate-count cap.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`engagement`})}),_jsxs(_components.td,{children:[`Current readings for every pending candidate, including newly sent candidates. Unknown counters are `,_jsx(_components.code,{children:`null`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`candidate_scores`})}),_jsx(_components.td,{children:`Proposed mapping for available admin snapshots. The existing wire shape requires this array, but it may be empty. Review its fields with the delivered model.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`removals`})}),_jsxs(_components.td,{children:[`Stop scoring the listed posts. Under the operator-independent policy, send only deleted/aged_out removals promptly; saved/hidden labels remain client-side. DCinside applies the 24-hour age filter and sends engagement every cycle until removal. See the `,_jsx(_components.a,{href:`/client#operator-independent-pool`,children:`worker handoff`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`published_windows`})}),_jsxs(_components.td,{children:[`Complete last-20 actual published snapshots, independently for `,_jsx(_components.code,{children:`main`}),` and `,_jsx(_components.code,{children:`light`}),`. Received posts need only identity and `,_jsx(_components.code,{children:`placed_at`}),`; posts never delivered need one-time title/body/image metadata in the window entry and JPEGs through the image route. Missing/null means unknown; `,_jsx(_components.code,{children:`[]`}),` asserts an empty feed. See `,_jsx(_components.a,{href:`/deduplication`,children:`Event deduplication`}),`.`]})]})]})]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`extracted_at`}),` means original entry into DCinside’s queue, including for posts delivered after an operator decision. Model 0924 first scores at or after `,_jsx(_components.code,{children:`extracted_at + 15 minutes`}),`. Before then, the result is `,_jsx(_components.code,{children:`waiting`}),`, with `,_jsx(_components.code,{children:`due_cycle`}),` set to the first five-minute boundary at or after that point. The target remains at least 99% first scored within two cycles after the 15-minute mark; reaching that target does not end retention. Saved/hidden decisions remain in that denominator; immediate deleted/aged_out removals before the mark retain the early-removal exclusion. A null entry time returns `,_jsx(_components.code,{children:`not_scored`}),` / `,_jsx(_components.code,{children:`missing_clock`}),`; a later retransmission can fill a previously unknown entry time, but cannot replace one already known.`]}),`\n`,_jsxs(_components.p,{children:[`New rehearsal candidates `,_jsxs(_components.strong,{children:[`must provide a non-null, RFC 3339 `,_jsx(_components.code,{children:`extracted_at`})]}),`. The field remains nullable on the API for compatibility and repair. A missing clock cannot establish scoring eligibility or prove the first-score SLA, and must not be silently removed from the 99% denominator; report and repair it. An early saved/hidden decision is not an exclusion under the new policy. The sending worker must validate queue-entry clocks before sending; the shared transport helper rejects missing or invalid candidate entry clocks.`]}),`\n`,_jsx(_components.p,{children:`Pending posts keep being rescored after their first score and after 25 minutes; the API has no automatic 24-hour expiry. The client sends deleted/aged_out removals when its deletion or age condition is met. The API applies received removals before scoring that cycle, so a candidate and its removal sent together do not obtain a first score. Saved/hidden enum values remain accepted for compatibility and still remove the post if received. Resending any removed identity does not revive it, including after restart; backfilling previously removed posts requires a separately agreed re-entry policy.`}),`\n`,_jsxs(_components.p,{children:[`Use the field reference below for proposed types and examples. JSON may be plain or gzip-compressed. Current size and array protections are listed in `,_jsx(_components.a,{href:`/conventions#current-service-protections`,children:`Conventions`}),`; do not truncate the full queue to fit them.`]}),`\n`,_jsx(Heading,{level:`2`,id:`response-and-retry-semantics`,children:`Response and retry semantics`}),`\n`,_jsxs(_components.p,{children:[`The response contains post IDs, final scores, model and weight versions, scoring times and counts. Per-part predictions are optional. All raw score rows remain present, including same-event duplicates. After raw scoring, the API durably prepares the cycle’s scores and exact candidate/published-window evidence, then allows background checks to progress within the remaining response budget before freezing one final response. The separate `,_jsx(_components.code,{children:`deduplication`}),` report compares candidates only against that cycle’s supplied windows. For Main and Light independently, `,_jsx(_components.code,{children:`ranked`}),` contains all scored candidates except confirmed `,_jsx(_components.code,{children:`duplicates`}),`; `,_jsx(_components.code,{children:`unchecked`}),` is a diagnostic subset of ranked and does not exclude candidates. Facts completed during this bounded wait can therefore appear in the same cycle. A newer cycle cannot substitute its window or scores into an older response.`]}),`\n`,_jsx(_components.p,{children:`Surf prioritizes the highest-scored work eligible to run. The wait ends when the prepared cycle’s still-needed comparisons have settled or its remaining wait budget expires; finding one usable candidate does not end the wait. Validated full-evidence unknowns and unavailable evidence can leave rows unchecked even when no further assessment is currently possible. Transient failures and incomplete evidence delivery remain retryable; a retry cooldown is not a completed check. A partial report includes unchecked candidates in ranked; only confirmed duplicates are excluded. Unchecked remains diagnostic, not proof of uniqueness. Missing content or a failed LLM check does not remove raw scores or certify those posts as unique.`}),`\n`,_jsxs(_components.p,{children:[`The latest client requirement allows `,_jsx(_components.strong,{children:`60 seconds from sending, including at most one retry`}),`. A late response is skipped for that cycle, but its data must still be reconciled. Recover using `,_jsx(_components.a,{href:`/scores`,children:_jsx(_components.code,{children:`GET /v1/scores/{cycle_id}`})}),` or replay the original request. See the `,_jsx(_components.a,{href:`/client`,children:`worker integration notes`}),` for retry budgeting. The server’s default 25-second processing budget includes preparation, raw scoring, bounded waiting and finalization, with time reserved to persist the response. Waiting releases the database writer so background results can commit. Background inference can continue after the response; this budget does not promise that every comparison resolves or prove the client’s end-to-end deadline.`]}),`\n`,_jsxs(_components.p,{children:[`New cycles may change scores and dedup decisions. Retries and GET for a completed cycle return its original response, including any partial/unavailable dedup result. Later images, a recovered provider, a background verdict or a different published snapshot do not rewrite that cycle. Send the next scheduled new cycle to receive an updated report; GET does not poll for newer verdicts. Changing a snapshot under an accepted cycle ID returns `,_jsx(_components.code,{children:`409`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`If a request stops after preparation but before finalization, replaying the unchanged request resumes its prepared scores, counts and evidence without scoring or ingesting them again. GET returns `,_jsx(_components.code,{children:`404`}),` until a final result exists. For newly prepared cycles, `,_jsx(_components.code,{children:`scored_at`}),` records raw model score completion before the deduplication wait; it is not the final response time or client round-trip duration.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`counts.candidates`}),` and `,_jsx(_components.code,{children:`counts.removals`}),` count identities first accepted in that cycle, excluding repeats within or across requests. Removal counts describe receipt, not when an operator decided; saved/hidden labels remain a separate client-side series and no longer generate removal receipts under this policy. `,_jsx(_components.code,{children:`counts.scored_now`}),` counts scoring events in that cycle, including rescoring, not unique first scores. For daily reconciliation, join by post identity, group unique entrants by original `,_jsx(_components.code,{children:`extracted_at`}),` KST date, and track first scores separately from per-cycle scoring and removal receipt. Between-cycle entrants increase the unique entrant totals. Original queue-entry and delivered removal timestamps are retained after removal. Removals remain effective after restart or candidate retransmission.`]}),`\n`,_jsxs(_components.p,{children:[`DCinside must record the actual policy switch time and cohort assignment. The proposed 2026-10-15 00:00 KST cycle `,_jsx(_components.code,{children:`20261015T0000`}),` is not confirmed; the earlier first-score-or-25-minute hold was never activated. Do not relabel historical measurements or infer a deployed policy period from a documentation update. Retrospective backfill of prior removals remains undecided. These API counters support reconciliation but do not calculate the first-score SLA denominator.`]}),`\n`,_jsxs(_components.p,{children:[`Scores use engagement and admin observations available through `,_jsx(_components.code,{children:`cycle_time`}),`, and age features at that time. Retaining a post after an operator decision does not produce an as-of-decision score: report these comparisons separately from scores available before the decision. Hidden alone does not veto a client pick under the new policy. The client skips currently real-board posts and selects the next eligible candidate; intervention follows actual publication/unpublication. A post already present in a supplied tier window is excluded from that tier’s dedup ranking while its raw score remains in `,_jsx(_components.code,{children:`results`}),`. Those last-20 snapshots do not replace the client’s full current-board check.`]}),`\n`,_jsx(_components.p,{children:`Examples illustrate the contract, not measured deployment results. Empty titles and unknown creation times can still be scored once queue-entry eligibility is known. Images may arrive later and do not delay scoring. DCinside applies the 24-hour queue filter and sends removals.`})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Score a Cycle","description":"Proposed rehearsal cycle payload and score response","openapi":"openapi.json POST /v1/cycles","href":"/cycles"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Proposed rehearsal behavior","slug":"proposed-rehearsal-behavior","depth":2,"children":[]},{"title":"Request guidance","slug":"request-guidance","depth":2,"children":[]},{"title":"Response and retry semantics","slug":"response-and-retry-semantics","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"operationId":"scoreCycle","tags":["Scoring"],"summary":"Score a Cycle","description":"Proposed rehearsal cycle payload and score response","parameters":["989bed00-46ea-4b50-aeb7-e15a1649eac3"],"requestBody":"438e0d19-1fb8-4a32-bbc1-3d40c78287e8","responses":{"200":"c565abf9-f616-4e91-be17-815677be6d9e","400":"e4e831b2-fc68-4b08-bd69-531b883416bf","401":"0891eae5-1684-435e-b21e-2e3c989b9d32","409":"c6980715-f405-45e3-bc4e-727ceaca5790","413":"2251b32f-7f08-4e76-8481-019e228dbe3d","422":"6b502312-5013-4526-bd97-428710060e45","500":"4d839c58-b0d6-423f-8a07-89527ded35fa","503":"a8e1c493-3983-4325-91d9-2265a4ad5281"},"method":"post","type":"path","servers":["d1723271-11ec-4bd0-a177-e7183babf553"],"security":["10858110-c05f-43f2-9504-99ddb0a1cf38"],"path":"/v1/cycles","baseUrlOptions":["https://dcinside-rtb-api.stg.kr.ask.surf"],"title":"Score a Cycle","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated","disableProxy":true},"dependencies":{"parameters":{"989bed00-46ea-4b50-aeb7-e15a1649eac3":{"name":"Content-Encoding","in":"header","required":false,"schema":{"type":"string","enum":["gzip"],"isRequired":false,"description":"Optional compression. Set to gzip only for a gzip-compressed body; plain JSON is also supported.","uniqueKey":"","typeLabel":"enum\u003cstring>"},"description":"Optional compression. Set to gzip only for a gzip-compressed body; plain JSON is also supported."}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"cycle_id":{"type":"string","pattern":"^\\d{8}T\\d{4}$","example":"20260929T0205","description":"Idempotency key: the cycle time in KST as `YYYYMMDDTHHMM`, for example `20260929T0205`. The same id with the same body returns the stored response. The same id with a different body returns 409.","isRequired":true,"uniqueKey":"cycle_id","typeLabel":"string"},"cycle_time":{"type":"string","format":"date-time","description":"Scheduled five-minute rehearsal boundary with an explicit RFC 3339 offset; normalize to KST for cycle_id. Up to 60 seconds ahead of server time is allowed, inclusive. Runtime supports other configured intervals outside this rehearsal.","example":"2026-09-29T02:05:00+09:00","pattern":"^\\d{4}-\\d{2}-\\d{2}[Tt]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:[Zz]|[+-]\\d{2}:\\d{2})$","isRequired":true,"uniqueKey":"cycle_time","typeLabel":"string\u003cdate-time>"},"candidates":{"type":"array","items":{"type":"object","properties":{"gall_id":{"type":"string","minLength":1,"description":"Post key, together with `post_no`.","example":"example_gallery","isRequired":true,"uniqueKey":"candidates.items.[INDEX].gall_id","typeLabel":"string"},"post_no":{"type":"integer","minimum":1,"description":"Post number. Unique only within a gallery, so a post is always keyed by `gall_id` and `post_no` together.","example":31900001,"isRequired":true,"uniqueKey":"candidates.items.[INDEX].post_no","typeLabel":"integer"},"title":{"type":"string","example":"Example original title","description":"Original extraction-time title before operator edits. Delivered field: queue.subject. Feature preprocessing and missing-title handling must be verified with Model 0924; they are not client-defined API limits.","isRequired":true,"uniqueKey":"candidates.items.[INDEX].title","typeLabel":"string"},"created_at":{"oneOf":[{"type":"string","format":"date-time","description":"Post creation time, used for age handling. RFC 3339 with explicit offset; null is accepted by the current parser but cannot supply a valid age. Delivered field: queue.created_at.","example":"2026-09-29T01:58:12+09:00","pattern":"^\\d{4}-\\d{2}-\\d{2}[Tt]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:[Zz]|[+-]\\d{2}:\\d{2})$","isRequired":true,"uniqueKey":"candidates.items.[INDEX].created_at.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","description":"Post creation time, used for age handling. RFC 3339 with explicit offset; null is accepted by the current parser but cannot supply a valid age. Delivered field: queue.created_at.","example":"2026-09-29T01:58:12+09:00","pattern":"^\\d{4}-\\d{2}-\\d{2}[Tt]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:[Zz]|[+-]\\d{2}:\\d{2})$","isRequired":true,"uniqueKey":"candidates.items.[INDEX].created_at.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"candidates.items.[INDEX].created_at","typeLabel":"string\u003cdate-time> | null"},"extracted_at":{"oneOf":[{"type":"string","format":"date-time","description":"Original queue entry, including posts captured after an operator decision. A known clock is retained on retransmission; scoring starts at or after this time plus 15 minutes. Rehearsal requires a non-null clock.","example":"2026-09-29T02:03:40+09:00","pattern":"^\\d{4}-\\d{2}-\\d{2}[Tt]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:[Zz]|[+-]\\d{2}:\\d{2})$","isRequired":true,"uniqueKey":"candidates.items.[INDEX].extracted_at.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","description":"Original queue entry, including posts captured after an operator decision. A known clock is retained on retransmission; scoring starts at or after this time plus 15 minutes. Rehearsal requires a non-null clock.","example":"2026-09-29T02:03:40+09:00","pattern":"^\\d{4}-\\d{2}-\\d{2}[Tt]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:[Zz]|[+-]\\d{2}:\\d{2})$","isRequired":true,"uniqueKey":"candidates.items.[INDEX].extracted_at.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"candidates.items.[INDEX].extracted_at","typeLabel":"string\u003cdate-time> | null"},"source":{"type":"string","enum":["score","setting","keyword","vote","manual","unknown"],"example":"keyword","description":"Original candidate source; use unknown when unavailable, including entrants captured between cycles.","isRequired":true,"uniqueKey":"candidates.items.[INDEX].source","typeLabel":"enum\u003cstring>"},"manual_flag":{"type":"integer","enum":[0,1],"example":0,"description":"1 when registered by hand from external monitoring. Proposed metadata mapping from queue.manual_flag; confirm requiredness during payload review.","isRequired":true,"uniqueKey":"candidates.items.[INDEX].manual_flag","typeLabel":"enum\u003cinteger>"},"images_in_post":{"type":"integer","minimum":0,"example":2,"description":"Original post image count from v1.3 image_manifest.images_in_post. Supplies Model0924 upimg_cnt only when the latest as-of admin snapshot value is missing/null; an explicit snapshot zero or other count wins. Never derived from received upload bytes.","isRequired":true,"uniqueKey":"candidates.items.[INDEX].images_in_post","typeLabel":"integer"},"image_positions":{"type":"array","uniqueItems":true,"items":{"type":"integer","minimum":1,"uniqueKey":"candidates.items.[INDEX].image_positions.items.[INDEX]","typeLabel":"integer"},"example":[1,2],"description":"Original one-based body positions expected for upload, preserving gaps for unavailable source images. Proposed mapping from v1.3 image_manifest.image_index.","uniqueKey":"candidates.items.[INDEX].image_positions","typeLabel":"integer[]"},"body_html":{"type":"string","example":"\u003cp>Example body\u003c/p>","description":"Original body text/HTML, delivered as queue.body_html. Text is sent once. Confirm body representation and model use during integration; do not infer optional source content from this draft field.","uniqueKey":"candidates.items.[INDEX].body_html","typeLabel":"string"},"gallery_type":{"type":"string","enum":["main","minor","mini"],"example":"minor","description":"Gallery type metadata. Confirm whether it is supplied directly or resolved through a gallery registry, including new and unknown galleries.","uniqueKey":"candidates.items.[INDEX].gallery_type","typeLabel":"enum\u003cstring>"},"category_id":{"type":"integer","example":12,"description":"Gallery category identifier from DCinside. Confirm the registry and mapping; there is no client-agreed numeric category range of 1–47.","uniqueKey":"candidates.items.[INDEX].category_id","typeLabel":"integer"}},"required":["gall_id","post_no","title","created_at","extracted_at","source","manual_flag","images_in_post"],"description":"Proposed new-candidate wire shape based on delivered data. Send text once after queue entry. Required metadata fields need client payload review.","uniqueKey":"candidates.items.[INDEX]","typeLabel":"object"},"description":"New posts since acknowledged delivery; re-include after uncertain timeout when GET finds no completed response. Identity gall_id/post_no is stored and counted once across repeated rows/cycles. Original content and known extracted_at remain unchanged. No candidate-count cap; the whole JSON body must fit within 16 MiB after decompression. Pending candidates remain until removed.","isRequired":true,"uniqueKey":"candidates","typeLabel":"object[]"},"engagement":{"type":"array","maxItems":5000,"items":{"type":"object","properties":{"gall_id":{"type":"string","minLength":1,"description":"Post key, together with `post_no`.","example":"example_gallery","isRequired":true,"uniqueKey":"engagement.items.[INDEX].gall_id","typeLabel":"string"},"post_no":{"type":"integer","minimum":1,"description":"Post number. Unique only within a gallery, so a post is always keyed by `gall_id` and `post_no` together.","example":31900001,"isRequired":true,"uniqueKey":"engagement.items.[INDEX].post_no","typeLabel":"integer"},"observed_at":{"type":"string","format":"date-time","description":"Time these counters were observed, with explicit offset, at or before cycle_time. Preserve source precision. Feature-window and freshness rules must be verified with the model and the agreed cadence. Delivered field: engagement_ts.ts.","example":"2026-09-29T02:04:00+09:00","pattern":"^\\d{4}-\\d{2}-\\d{2}[Tt]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:[Zz]|[+-]\\d{2}:\\d{2})$","isRequired":true,"uniqueKey":"engagement.items.[INDEX].observed_at","typeLabel":"string\u003cdate-time>"},"status":{"type":"string","enum":["ok","missing","nomap"],"example":"ok","description":"Delivered observation state: ok, missing or nomap. The current adapter excludes missing/nomap rows from scoring. Confirm missing-data handling with the real model.","isRequired":true,"uniqueKey":"engagement.items.[INDEX].status","typeLabel":"enum\u003cstring>"},"views":{"oneOf":[{"type":"integer","minimum":0,"description":"Current view count. Keep null for an unknown reading. Surf can derive engagement history from successive observations; feature details must match the delivered model.","example":412,"isRequired":true,"uniqueKey":"engagement.items.[INDEX].views.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"description":"Current view count. Keep null for an unknown reading. Surf can derive engagement history from successive observations; feature details must match the delivered model.","example":412,"isRequired":true,"uniqueKey":"engagement.items.[INDEX].views.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"engagement.items.[INDEX].views","typeLabel":"integer | null"},"up":{"oneOf":[{"type":"integer","minimum":0,"description":"Recommendations, not the Send-to-Best counter. In v1 and v1.1 of the delivered files this column held the wrong counter, and v1.2 corrected it.","example":9,"isRequired":true,"uniqueKey":"engagement.items.[INDEX].up.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"description":"Recommendations, not the Send-to-Best counter. In v1 and v1.1 of the delivered files this column held the wrong counter, and v1.2 corrected it.","example":9,"isRequired":true,"uniqueKey":"engagement.items.[INDEX].up.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"engagement.items.[INDEX].up","typeLabel":"integer | null"},"down":{"oneOf":[{"type":"integer","minimum":0,"description":"Down-votes. Feeds the down-vote share input.","example":1,"isRequired":true,"uniqueKey":"engagement.items.[INDEX].down.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"description":"Down-votes. Feeds the down-vote share input.","example":1,"isRequired":true,"uniqueKey":"engagement.items.[INDEX].down.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"engagement.items.[INDEX].down","typeLabel":"integer | null"},"comment_cnt":{"oneOf":[{"type":"integer","minimum":0,"description":"Comment count.","example":6,"isRequired":true,"uniqueKey":"engagement.items.[INDEX].comment_cnt.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"description":"Comment count.","example":6,"isRequired":true,"uniqueKey":"engagement.items.[INDEX].comment_cnt.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"engagement.items.[INDEX].comment_cnt","typeLabel":"integer | null"},"rtb_vote":{"oneOf":[{"type":"integer","minimum":0,"description":"Send-to-Best votes, distinct from recommendations (up). This additional wire field is proposed for review, not a separate client requirement.","example":0,"isRequired":true,"uniqueKey":"engagement.items.[INDEX].rtb_vote.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"description":"Send-to-Best votes, distinct from recommendations (up). This additional wire field is proposed for review, not a separate client requirement.","example":0,"isRequired":true,"uniqueKey":"engagement.items.[INDEX].rtb_vote.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"engagement.items.[INDEX].rtb_vote","typeLabel":"integer | null"}},"required":["gall_id","post_no","observed_at","status","views","up","down","comment_cnt","rtb_vote"],"description":"Current counters of one pending post, as read from the gallery.","uniqueKey":"engagement.items.[INDEX]","typeLabel":"object"},"description":"One row for every pending candidate, every cycle. Pending means sent in this or an earlier call and not yet in `removals`. The current 5,000-row cap is an engineering protection, not an agreed business quota; validate it against full-queue delivery.","isRequired":true,"uniqueKey":"engagement","typeLabel":"object[]"},"candidate_scores":{"type":"array","maxItems":5000,"items":{"type":"object","properties":{"gall_id":{"type":"string","minLength":1,"description":"Post key, together with `post_no`.","example":"example_gallery","isRequired":true,"uniqueKey":"candidate_scores.items.[INDEX].gall_id","typeLabel":"string"},"post_no":{"type":"integer","minimum":1,"description":"Post number. Unique only within a gallery, so a post is always keyed by `gall_id` and `post_no` together.","example":31900001,"isRequired":true,"uniqueKey":"candidate_scores.items.[INDEX].post_no","typeLabel":"integer"},"snapshot_at":{"type":"string","format":"date-time","description":"Time the admin candidate-score table was read, at or before cycle_time. Delivered field: candidate_score_ts.snapshot_ts.","example":"2026-09-29T02:05:00+09:00","pattern":"^\\d{4}-\\d{2}-\\d{2}[Tt]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:[Zz]|[+-]\\d{2}:\\d{2})$","isRequired":true,"uniqueKey":"candidate_scores.items.[INDEX].snapshot_at","typeLabel":"string\u003cdate-time>"},"recommend_up_cnt":{"oneOf":[{"type":"integer","minimum":0,"description":"Over-baseline recommendations, PC part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":3,"uniqueKey":"candidate_scores.items.[INDEX].recommend_up_cnt.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"description":"Over-baseline recommendations, PC part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":3,"uniqueKey":"candidate_scores.items.[INDEX].recommend_up_cnt.oneOf.1","typeLabel":"null"}],"uniqueKey":"candidate_scores.items.[INDEX].recommend_up_cnt","typeLabel":"integer | null"},"recommend_up_cnt_m":{"oneOf":[{"type":"integer","minimum":0,"description":"Over-baseline recommendations, mobile part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":2,"uniqueKey":"candidate_scores.items.[INDEX].recommend_up_cnt_m.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"description":"Over-baseline recommendations, mobile part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":2,"uniqueKey":"candidate_scores.items.[INDEX].recommend_up_cnt_m.oneOf.1","typeLabel":"null"}],"uniqueKey":"candidate_scores.items.[INDEX].recommend_up_cnt_m","typeLabel":"integer | null"},"recommend_up_cnt_a":{"oneOf":[{"type":"integer","minimum":0,"description":"Over-baseline recommendations, app part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":1,"uniqueKey":"candidate_scores.items.[INDEX].recommend_up_cnt_a.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"description":"Over-baseline recommendations, app part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":1,"uniqueKey":"candidate_scores.items.[INDEX].recommend_up_cnt_a.oneOf.1","typeLabel":"null"}],"uniqueKey":"candidate_scores.items.[INDEX].recommend_up_cnt_a","typeLabel":"integer | null"},"comment_cnt":{"oneOf":[{"type":"integer","minimum":0,"description":"Over-baseline comments, PC part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":2,"uniqueKey":"candidate_scores.items.[INDEX].comment_cnt.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"description":"Over-baseline comments, PC part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":2,"uniqueKey":"candidate_scores.items.[INDEX].comment_cnt.oneOf.1","typeLabel":"null"}],"uniqueKey":"candidate_scores.items.[INDEX].comment_cnt","typeLabel":"integer | null"},"comment_cnt_m":{"oneOf":[{"type":"integer","minimum":0,"description":"Over-baseline comments, mobile part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":1,"uniqueKey":"candidate_scores.items.[INDEX].comment_cnt_m.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"description":"Over-baseline comments, mobile part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":1,"uniqueKey":"candidate_scores.items.[INDEX].comment_cnt_m.oneOf.1","typeLabel":"null"}],"uniqueKey":"candidate_scores.items.[INDEX].comment_cnt_m","typeLabel":"integer | null"},"comment_cnt_a":{"oneOf":[{"type":"integer","minimum":0,"description":"Over-baseline comments, app part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":1,"uniqueKey":"candidate_scores.items.[INDEX].comment_cnt_a.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"description":"Over-baseline comments, app part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":1,"uniqueKey":"candidate_scores.items.[INDEX].comment_cnt_a.oneOf.1","typeLabel":"null"}],"uniqueKey":"candidate_scores.items.[INDEX].comment_cnt_a","typeLabel":"integer | null"},"hit_cnt":{"oneOf":[{"type":"integer","minimum":0,"description":"Over-baseline views, PC part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":5,"uniqueKey":"candidate_scores.items.[INDEX].hit_cnt.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"description":"Over-baseline views, PC part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":5,"uniqueKey":"candidate_scores.items.[INDEX].hit_cnt.oneOf.1","typeLabel":"null"}],"uniqueKey":"candidate_scores.items.[INDEX].hit_cnt","typeLabel":"integer | null"},"hit_cnt_m":{"oneOf":[{"type":"integer","minimum":0,"description":"Over-baseline views, mobile part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":4,"uniqueKey":"candidate_scores.items.[INDEX].hit_cnt_m.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"description":"Over-baseline views, mobile part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":4,"uniqueKey":"candidate_scores.items.[INDEX].hit_cnt_m.oneOf.1","typeLabel":"null"}],"uniqueKey":"candidate_scores.items.[INDEX].hit_cnt_m","typeLabel":"integer | null"},"hit_cnt_a":{"oneOf":[{"type":"integer","minimum":0,"description":"Over-baseline views, app part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":1,"uniqueKey":"candidate_scores.items.[INDEX].hit_cnt_a.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"description":"Over-baseline views, app part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":1,"uniqueKey":"candidate_scores.items.[INDEX].hit_cnt_a.oneOf.1","typeLabel":"null"}],"uniqueKey":"candidate_scores.items.[INDEX].hit_cnt_a","typeLabel":"integer | null"},"dcbest_cnt":{"oneOf":[{"type":"integer","minimum":0,"description":"Send-to-Best votes, PC part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":0,"uniqueKey":"candidate_scores.items.[INDEX].dcbest_cnt.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"description":"Send-to-Best votes, PC part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":0,"uniqueKey":"candidate_scores.items.[INDEX].dcbest_cnt.oneOf.1","typeLabel":"null"}],"uniqueKey":"candidate_scores.items.[INDEX].dcbest_cnt","typeLabel":"integer | null"},"dcbest_cnt_m":{"oneOf":[{"type":"integer","minimum":0,"description":"Send-to-Best votes, mobile part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":0,"uniqueKey":"candidate_scores.items.[INDEX].dcbest_cnt_m.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"description":"Send-to-Best votes, mobile part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":0,"uniqueKey":"candidate_scores.items.[INDEX].dcbest_cnt_m.oneOf.1","typeLabel":"null"}],"uniqueKey":"candidate_scores.items.[INDEX].dcbest_cnt_m","typeLabel":"integer | null"},"dcbest_cnt_a":{"oneOf":[{"type":"integer","minimum":0,"description":"Send-to-Best votes, app part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":0,"uniqueKey":"candidate_scores.items.[INDEX].dcbest_cnt_a.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"description":"Send-to-Best votes, app part. Proposed source mapping; confirm feature aggregation with the delivered model.","example":0,"uniqueKey":"candidate_scores.items.[INDEX].dcbest_cnt_a.oneOf.1","typeLabel":"null"}],"uniqueKey":"candidate_scores.items.[INDEX].dcbest_cnt_a","typeLabel":"integer | null"},"memo_size":{"oneOf":[{"type":"integer","minimum":0,"description":"Body size as the admin table counts it. A model input as delivered, so there is nothing to compute on DCinside's side.","example":1840,"uniqueKey":"candidate_scores.items.[INDEX].memo_size.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"description":"Body size as the admin table counts it. A model input as delivered, so there is nothing to compute on DCinside's side.","example":1840,"uniqueKey":"candidate_scores.items.[INDEX].memo_size.oneOf.1","typeLabel":"null"}],"uniqueKey":"candidate_scores.items.[INDEX].memo_size","typeLabel":"integer | null"},"upimg_cnt":{"oneOf":[{"type":"integer","minimum":0,"description":"Admin snapshot image count. Latest as-of value takes precedence over candidate images_in_post, including explicit zero. Missing/null falls back to candidate metadata without waiting for uploads.","example":2,"uniqueKey":"candidate_scores.items.[INDEX].upimg_cnt.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"description":"Admin snapshot image count. Latest as-of value takes precedence over candidate images_in_post, including explicit zero. Missing/null falls back to candidate metadata without waiting for uploads.","example":2,"uniqueKey":"candidate_scores.items.[INDEX].upimg_cnt.oneOf.1","typeLabel":"null"}],"uniqueKey":"candidate_scores.items.[INDEX].upimg_cnt","typeLabel":"integer | null"},"upimg_height":{"oneOf":[{"type":"integer","minimum":0,"maximum":32767,"example":2410,"description":"Total uploaded-image height as delivered, capped at 32,767 in the source export. This is a source-field convention, not a queue or image-count limit.","uniqueKey":"candidate_scores.items.[INDEX].upimg_height.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"maximum":32767,"example":2410,"description":"Total uploaded-image height as delivered, capped at 32,767 in the source export. This is a source-field convention, not a queue or image-count limit.","uniqueKey":"candidate_scores.items.[INDEX].upimg_height.oneOf.1","typeLabel":"null"}],"uniqueKey":"candidate_scores.items.[INDEX].upimg_height","typeLabel":"integer | null"}},"required":["gall_id","post_no","snapshot_at"],"description":"Optional available admin-snapshot data carried in the proposed candidate_scores array. Verify the required features against Model 0924; the array may be empty.","uniqueKey":"candidate_scores.items.[INDEX]","typeLabel":"object"},"description":"Available admin snapshots, when present. Existing wire shape requires the array but permits []. Confirm feature mapping and requiredness with the client and delivered model. The current 5,000-row cap is an engineering protection, not an agreed business quota; validate it against full-queue delivery.","isRequired":true,"uniqueKey":"candidate_scores","typeLabel":"object[]"},"removals":{"type":"array","maxItems":5000,"items":{"type":"object","properties":{"gall_id":{"type":"string","minLength":1,"description":"Post key, together with `post_no`.","example":"example_gallery","isRequired":true,"uniqueKey":"removals.items.[INDEX].gall_id","typeLabel":"string"},"post_no":{"type":"integer","minimum":1,"description":"Post number. Unique only within a gallery, so a post is always keyed by `gall_id` and `post_no` together.","example":31900001,"isRequired":true,"uniqueKey":"removals.items.[INDEX].post_no","typeLabel":"integer"},"reason":{"type":"string","enum":["saved","hidden","deleted","aged_out"],"example":"hidden","description":"Received removals take effect before scoring and cannot be undone by resending candidates. Under the operator-independent sender policy, only deleted/aged_out are emitted; saved/hidden labels do not end pending retention. Saved/hidden remain accepted for compatibility and still remove the post; saved requires tier. The client applies the 24-hour age filter; there is no automatic server expiry.","isRequired":true,"uniqueKey":"removals.items.[INDEX].reason","typeLabel":"enum\u003cstring>"},"decided_at":{"type":"string","format":"date-time","description":"Original decision time, preserved when delivery is delayed. Requires an explicit offset and must not be after cycle_time; no recency requirement.","example":"2026-09-29T02:01:10+09:00","pattern":"^\\d{4}-\\d{2}-\\d{2}[Tt]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:[Zz]|[+-]\\d{2}:\\d{2})$","isRequired":true,"uniqueKey":"removals.items.[INDEX].decided_at","typeLabel":"string\u003cdate-time>"},"tier":{"type":"string","enum":["main","light","night","app"],"example":"main","description":"Board tier; required for saved removals as confirmed in the September 30 client reply.","uniqueKey":"removals.items.[INDEX].tier","typeLabel":"enum\u003cstring>"},"reason_code":{"type":"string","example":"quota_full","description":"Optional operator reason code. The code list and delivery mapping remain to be agreed; do not infer a fixed enumeration from this example.","uniqueKey":"removals.items.[INDEX].reason_code","typeLabel":"string"}},"required":["gall_id","post_no","reason","decided_at"],"description":"A post leaving the pending pool.","uniqueKey":"removals.items.[INDEX]","typeLabel":"object"},"description":"Saved, hidden, deleted or aged-out post identities. Re-inclusion within/across cycles is idempotent and counts only first accepted removals; candidate retransmission cannot revive a removed post.","isRequired":true,"uniqueKey":"removals","typeLabel":"object[]"},"published_windows":{"oneOf":[{"type":"object","title":"PublishedWindows","description":"Optional independent current last20 Main/Light published snapshots. Required for published-window dedup coverage; omission/null stays unknown, while [] asserts an empty feed. References reuse archived evidence. For never-delivered posts, bootstrap title/body/image metadata once here, with JPEGs uploaded separately; do not add them as pending candidates.","properties":{"main":{"oneOf":[{"default":null,"title":"Main","items":{"description":"Actual published post reference, with optional once-only evidence bootstrap.\n\nReferences reuse archived candidate content and uploaded images. For a post\nnever delivered before, supply title/body and image metadata here once;\nupload JPEG bytes through the existing image route, not this JSON object.\nMissing evidence remains unchecked; bootstrap does not create a candidate.","properties":{"gall_id":{"title":"Gall Id","type":"string","isRequired":true,"uniqueKey":"published_windows.oneOf.0.main.oneOf.0.items.[INDEX].gall_id","typeLabel":"string"},"post_no":{"title":"Post No","type":"integer","isRequired":true,"uniqueKey":"published_windows.oneOf.0.main.oneOf.0.items.[INDEX].post_no","typeLabel":"integer"},"placed_at":{"description":"Actual publication time with an explicit offset, no later than cycle_time. A quiet feed may contain old posts; there is no age expiry.","format":"date-time","title":"Placed At","type":"string","isRequired":true,"uniqueKey":"published_windows.oneOf.0.main.oneOf.0.items.[INDEX].placed_at","typeLabel":"string\u003cdate-time>"},"title":{"oneOf":[{"default":null,"description":"Once-only bootstrap when archived title is missing. Omit after delivery; existing candidate evidence is preserved.","title":"Title","type":"string","uniqueKey":"published_windows.oneOf.0.main.oneOf.0.items.[INDEX].title.oneOf.0","typeLabel":"string"},{"default":null,"description":"Once-only bootstrap when archived title is missing. Omit after delivery; existing candidate evidence is preserved.","title":"Title","type":"null","uniqueKey":"published_windows.oneOf.0.main.oneOf.0.items.[INDEX].title.oneOf.1","typeLabel":"null"}],"uniqueKey":"published_windows.oneOf.0.main.oneOf.0.items.[INDEX].title","typeLabel":"string | null"},"body_html":{"oneOf":[{"default":null,"description":"Once-only original body when archived content is missing. Image URLs in HTML are not fetched.","title":"Body Html","type":"string","uniqueKey":"published_windows.oneOf.0.main.oneOf.0.items.[INDEX].body_html.oneOf.0","typeLabel":"string"},{"default":null,"description":"Once-only original body when archived content is missing. Image URLs in HTML are not fetched.","title":"Body Html","type":"null","uniqueKey":"published_windows.oneOf.0.main.oneOf.0.items.[INDEX].body_html.oneOf.1","typeLabel":"null"}],"uniqueKey":"published_windows.oneOf.0.main.oneOf.0.items.[INDEX].body_html","typeLabel":"string | null"},"images_in_post":{"oneOf":[{"default":null,"description":"Accurate original image count for bootstrap; metadata is not image evidence. Omission preserves archived metadata.","title":"Images In Post","minimum":0,"type":"integer","uniqueKey":"published_windows.oneOf.0.main.oneOf.0.items.[INDEX].images_in_post.oneOf.0","typeLabel":"integer"},{"default":null,"description":"Accurate original image count for bootstrap; metadata is not image evidence. Omission preserves archived metadata.","title":"Images In Post","minimum":0,"type":"null","uniqueKey":"published_windows.oneOf.0.main.oneOf.0.items.[INDEX].images_in_post.oneOf.1","typeLabel":"null"}],"uniqueKey":"published_windows.oneOf.0.main.oneOf.0.items.[INDEX].images_in_post","typeLabel":"integer | null"},"image_positions":{"oneOf":[{"default":null,"description":"Original image positions for bootstrap. Upload JPEGs separately with PUT /v1/images/{gall_id}/{post_no}/{NN}.","title":"Image Positions","items":{"maximum":999,"minimum":0,"type":"integer","uniqueKey":"published_windows.oneOf.0.main.oneOf.0.items.[INDEX].image_positions.oneOf.0.items.[INDEX]","typeLabel":"integer"},"type":"array","uniqueKey":"published_windows.oneOf.0.main.oneOf.0.items.[INDEX].image_positions.oneOf.0","typeLabel":"integer[]"},{"default":null,"description":"Original image positions for bootstrap. Upload JPEGs separately with PUT /v1/images/{gall_id}/{post_no}/{NN}.","title":"Image Positions","items":{"maximum":999,"minimum":0,"type":"integer"},"type":"null","uniqueKey":"published_windows.oneOf.0.main.oneOf.0.items.[INDEX].image_positions.oneOf.1","typeLabel":"null"}],"uniqueKey":"published_windows.oneOf.0.main.oneOf.0.items.[INDEX].image_positions","typeLabel":"integer[] | null"}},"required":["gall_id","post_no","placed_at"],"title":"PublishedPost","type":"object","uniqueKey":"published_windows.oneOf.0.main.oneOf.0.items.[INDEX]","typeLabel":"PublishedPost · object"},"maxItems":20,"type":"array","uniqueKey":"published_windows.oneOf.0.main.oneOf.0","typeLabel":"PublishedPost · object[]"},{"default":null,"title":"Main","items":{"description":"Actual published post reference, with optional once-only evidence bootstrap.\n\nReferences reuse archived candidate content and uploaded images. For a post\nnever delivered before, supply title/body and image metadata here once;\nupload JPEG bytes through the existing image route, not this JSON object.\nMissing evidence remains unchecked; bootstrap does not create a candidate.","properties":{"gall_id":{"title":"Gall Id","type":"string"},"post_no":{"title":"Post No","type":"integer"},"placed_at":{"description":"Actual publication time with an explicit offset, no later than cycle_time. A quiet feed may contain old posts; there is no age expiry.","format":"date-time","title":"Placed At","type":"string"},"title":{"oneOf":[{"default":null,"description":"Once-only bootstrap when archived title is missing. Omit after delivery; existing candidate evidence is preserved.","title":"Title","type":"string"},{"default":null,"description":"Once-only bootstrap when archived title is missing. Omit after delivery; existing candidate evidence is preserved.","title":"Title","type":"null"}]},"body_html":{"oneOf":[{"default":null,"description":"Once-only original body when archived content is missing. Image URLs in HTML are not fetched.","title":"Body Html","type":"string"},{"default":null,"description":"Once-only original body when archived content is missing. Image URLs in HTML are not fetched.","title":"Body Html","type":"null"}]},"images_in_post":{"oneOf":[{"default":null,"description":"Accurate original image count for bootstrap; metadata is not image evidence. Omission preserves archived metadata.","title":"Images In Post","minimum":0,"type":"integer"},{"default":null,"description":"Accurate original image count for bootstrap; metadata is not image evidence. Omission preserves archived metadata.","title":"Images In Post","minimum":0,"type":"null"}]},"image_positions":{"oneOf":[{"default":null,"description":"Original image positions for bootstrap. Upload JPEGs separately with PUT /v1/images/{gall_id}/{post_no}/{NN}.","title":"Image Positions","items":{"maximum":999,"minimum":0,"type":"integer"},"type":"array"},{"default":null,"description":"Original image positions for bootstrap. Upload JPEGs separately with PUT /v1/images/{gall_id}/{post_no}/{NN}.","title":"Image Positions","items":{"maximum":999,"minimum":0,"type":"integer"},"type":"null"}]}},"required":["gall_id","post_no","placed_at"],"title":"PublishedPost","type":"object"},"maxItems":20,"type":"null","uniqueKey":"published_windows.oneOf.0.main.oneOf.1","typeLabel":"null"}],"uniqueKey":"published_windows.oneOf.0.main","typeLabel":"PublishedPost · object[] | null"},"light":{"oneOf":[{"default":null,"title":"Light","items":{"description":"Actual published post reference, with optional once-only evidence bootstrap.\n\nReferences reuse archived candidate content and uploaded images. For a post\nnever delivered before, supply title/body and image metadata here once;\nupload JPEG bytes through the existing image route, not this JSON object.\nMissing evidence remains unchecked; bootstrap does not create a candidate.","properties":{"gall_id":{"title":"Gall Id","type":"string","isRequired":true,"uniqueKey":"published_windows.oneOf.0.light.oneOf.0.items.[INDEX].gall_id","typeLabel":"string"},"post_no":{"title":"Post No","type":"integer","isRequired":true,"uniqueKey":"published_windows.oneOf.0.light.oneOf.0.items.[INDEX].post_no","typeLabel":"integer"},"placed_at":{"description":"Actual publication time with an explicit offset, no later than cycle_time. A quiet feed may contain old posts; there is no age expiry.","format":"date-time","title":"Placed At","type":"string","isRequired":true,"uniqueKey":"published_windows.oneOf.0.light.oneOf.0.items.[INDEX].placed_at","typeLabel":"string\u003cdate-time>"},"title":{"oneOf":[{"default":null,"description":"Once-only bootstrap when archived title is missing. Omit after delivery; existing candidate evidence is preserved.","title":"Title","type":"string","uniqueKey":"published_windows.oneOf.0.light.oneOf.0.items.[INDEX].title.oneOf.0","typeLabel":"string"},{"default":null,"description":"Once-only bootstrap when archived title is missing. Omit after delivery; existing candidate evidence is preserved.","title":"Title","type":"null","uniqueKey":"published_windows.oneOf.0.light.oneOf.0.items.[INDEX].title.oneOf.1","typeLabel":"null"}],"uniqueKey":"published_windows.oneOf.0.light.oneOf.0.items.[INDEX].title","typeLabel":"string | null"},"body_html":{"oneOf":[{"default":null,"description":"Once-only original body when archived content is missing. Image URLs in HTML are not fetched.","title":"Body Html","type":"string","uniqueKey":"published_windows.oneOf.0.light.oneOf.0.items.[INDEX].body_html.oneOf.0","typeLabel":"string"},{"default":null,"description":"Once-only original body when archived content is missing. Image URLs in HTML are not fetched.","title":"Body Html","type":"null","uniqueKey":"published_windows.oneOf.0.light.oneOf.0.items.[INDEX].body_html.oneOf.1","typeLabel":"null"}],"uniqueKey":"published_windows.oneOf.0.light.oneOf.0.items.[INDEX].body_html","typeLabel":"string | null"},"images_in_post":{"oneOf":[{"default":null,"description":"Accurate original image count for bootstrap; metadata is not image evidence. Omission preserves archived metadata.","title":"Images In Post","minimum":0,"type":"integer","uniqueKey":"published_windows.oneOf.0.light.oneOf.0.items.[INDEX].images_in_post.oneOf.0","typeLabel":"integer"},{"default":null,"description":"Accurate original image count for bootstrap; metadata is not image evidence. Omission preserves archived metadata.","title":"Images In Post","minimum":0,"type":"null","uniqueKey":"published_windows.oneOf.0.light.oneOf.0.items.[INDEX].images_in_post.oneOf.1","typeLabel":"null"}],"uniqueKey":"published_windows.oneOf.0.light.oneOf.0.items.[INDEX].images_in_post","typeLabel":"integer | null"},"image_positions":{"oneOf":[{"default":null,"description":"Original image positions for bootstrap. Upload JPEGs separately with PUT /v1/images/{gall_id}/{post_no}/{NN}.","title":"Image Positions","items":{"maximum":999,"minimum":0,"type":"integer","uniqueKey":"published_windows.oneOf.0.light.oneOf.0.items.[INDEX].image_positions.oneOf.0.items.[INDEX]","typeLabel":"integer"},"type":"array","uniqueKey":"published_windows.oneOf.0.light.oneOf.0.items.[INDEX].image_positions.oneOf.0","typeLabel":"integer[]"},{"default":null,"description":"Original image positions for bootstrap. Upload JPEGs separately with PUT /v1/images/{gall_id}/{post_no}/{NN}.","title":"Image Positions","items":{"maximum":999,"minimum":0,"type":"integer"},"type":"null","uniqueKey":"published_windows.oneOf.0.light.oneOf.0.items.[INDEX].image_positions.oneOf.1","typeLabel":"null"}],"uniqueKey":"published_windows.oneOf.0.light.oneOf.0.items.[INDEX].image_positions","typeLabel":"integer[] | null"}},"required":["gall_id","post_no","placed_at"],"title":"PublishedPost","type":"object","uniqueKey":"published_windows.oneOf.0.light.oneOf.0.items.[INDEX]","typeLabel":"PublishedPost · object"},"maxItems":20,"type":"array","uniqueKey":"published_windows.oneOf.0.light.oneOf.0","typeLabel":"PublishedPost · object[]"},{"default":null,"title":"Light","items":{"description":"Actual published post reference, with optional once-only evidence bootstrap.\n\nReferences reuse archived candidate content and uploaded images. For a post\nnever delivered before, supply title/body and image metadata here once;\nupload JPEG bytes through the existing image route, not this JSON object.\nMissing evidence remains unchecked; bootstrap does not create a candidate.","properties":{"gall_id":{"title":"Gall Id","type":"string"},"post_no":{"title":"Post No","type":"integer"},"placed_at":{"description":"Actual publication time with an explicit offset, no later than cycle_time. A quiet feed may contain old posts; there is no age expiry.","format":"date-time","title":"Placed At","type":"string"},"title":{"oneOf":[{"default":null,"description":"Once-only bootstrap when archived title is missing. Omit after delivery; existing candidate evidence is preserved.","title":"Title","type":"string"},{"default":null,"description":"Once-only bootstrap when archived title is missing. Omit after delivery; existing candidate evidence is preserved.","title":"Title","type":"null"}]},"body_html":{"oneOf":[{"default":null,"description":"Once-only original body when archived content is missing. Image URLs in HTML are not fetched.","title":"Body Html","type":"string"},{"default":null,"description":"Once-only original body when archived content is missing. Image URLs in HTML are not fetched.","title":"Body Html","type":"null"}]},"images_in_post":{"oneOf":[{"default":null,"description":"Accurate original image count for bootstrap; metadata is not image evidence. Omission preserves archived metadata.","title":"Images In Post","minimum":0,"type":"integer"},{"default":null,"description":"Accurate original image count for bootstrap; metadata is not image evidence. Omission preserves archived metadata.","title":"Images In Post","minimum":0,"type":"null"}]},"image_positions":{"oneOf":[{"default":null,"description":"Original image positions for bootstrap. Upload JPEGs separately with PUT /v1/images/{gall_id}/{post_no}/{NN}.","title":"Image Positions","items":{"maximum":999,"minimum":0,"type":"integer"},"type":"array"},{"default":null,"description":"Original image positions for bootstrap. Upload JPEGs separately with PUT /v1/images/{gall_id}/{post_no}/{NN}.","title":"Image Positions","items":{"maximum":999,"minimum":0,"type":"integer"},"type":"null"}]}},"required":["gall_id","post_no","placed_at"],"title":"PublishedPost","type":"object"},"maxItems":20,"type":"null","uniqueKey":"published_windows.oneOf.0.light.oneOf.1","typeLabel":"null"}],"uniqueKey":"published_windows.oneOf.0.light","typeLabel":"PublishedPost · object[] | null"}},"uniqueKey":"published_windows.oneOf.0","typeLabel":"PublishedWindows · object"},{"type":"null","uniqueKey":"published_windows.oneOf.1","typeLabel":"null"}],"uniqueKey":"published_windows","typeLabel":"PublishedWindows · object | null"}},"required":["cycle_id","cycle_time","candidates","engagement","candidate_scores","removals"],"description":"Proposed rehearsal wire shape. Required arrays and extra metadata need payload review. Current other-array and request-size protections are engineering limits, not client quotas.","uniqueKey":"","typeLabel":"object"},"example":{"cycle_id":"20260929T0205","cycle_time":"2026-09-29T02:05:00+09:00","candidates":[{"gall_id":"example_gallery","post_no":31900001,"title":"Example original title","created_at":"2026-09-29T01:40:12+09:00","extracted_at":"2026-09-29T01:49:40+09:00","source":"keyword","manual_flag":0,"images_in_post":2}],"engagement":[{"gall_id":"example_gallery","post_no":31900001,"observed_at":"2026-09-29T02:04:00+09:00","status":"ok","views":412,"up":9,"down":1,"comment_cnt":6,"rtb_vote":0},{"gall_id":"example_gallery","post_no":31899120,"observed_at":"2026-09-29T02:04:00+09:00","status":"ok","views":1875,"up":null,"down":null,"comment_cnt":21,"rtb_vote":0}],"candidate_scores":[{"gall_id":"example_gallery","post_no":31900001,"snapshot_at":"2026-09-29T02:05:00+09:00","recommend_up_cnt":3,"recommend_up_cnt_m":2,"recommend_up_cnt_a":1,"comment_cnt":2,"comment_cnt_m":1,"comment_cnt_a":0,"hit_cnt":5,"hit_cnt_m":3,"hit_cnt_a":1,"dcbest_cnt":0,"dcbest_cnt_m":0,"dcbest_cnt_a":0,"memo_size":1840,"upimg_cnt":2,"upimg_height":2410}],"removals":[{"gall_id":"example_gallery","post_no":31898050,"reason":"deleted","decided_at":"2026-09-29T02:01:10+09:00"}]},"examples":{"Example":{"title":"Example","value":{"cycle_id":"20260929T0205","cycle_time":"2026-09-29T02:05:00+09:00","candidates":[{"gall_id":"example_gallery","post_no":31900001,"title":"Example original title","created_at":"2026-09-29T01:40:12+09:00","extracted_at":"2026-09-29T01:49:40+09:00","source":"keyword","manual_flag":0,"images_in_post":2}],"engagement":[{"gall_id":"example_gallery","post_no":31900001,"observed_at":"2026-09-29T02:04:00+09:00","status":"ok","views":412,"up":9,"down":1,"comment_cnt":6,"rtb_vote":0},{"gall_id":"example_gallery","post_no":31899120,"observed_at":"2026-09-29T02:04:00+09:00","status":"ok","views":1875,"up":null,"down":null,"comment_cnt":21,"rtb_vote":0}],"candidate_scores":[{"gall_id":"example_gallery","post_no":31900001,"snapshot_at":"2026-09-29T02:05:00+09:00","recommend_up_cnt":3,"recommend_up_cnt_m":2,"recommend_up_cnt_a":1,"comment_cnt":2,"comment_cnt_m":1,"comment_cnt_a":0,"hit_cnt":5,"hit_cnt_m":3,"hit_cnt_a":1,"dcbest_cnt":0,"dcbest_cnt_m":0,"dcbest_cnt_a":0,"memo_size":1840,"upimg_cnt":2,"upimg_height":2410}],"removals":[{"gall_id":"example_gallery","post_no":31898050,"reason":"deleted","decided_at":"2026-09-29T02:01:10+09:00"}]}}},"exampleType":"examples"}},"exampleType":"examples"},"responses":{"c565abf9-f616-4e91-be17-815677be6d9e":{"description":"Complete raw scores and the immutable deduplication report for this cycle. Provider failure can return 200 with raw scores and explicit unavailable/unchecked deduplication.","content":{"application/json":{"schema":{"type":"object","properties":{"cycle_id":{"type":"string","pattern":"^\\d{8}T\\d{4}$","example":"20260929T0205","description":"Echoed from the request.","isRequired":true,"uniqueKey":"cycle_id","typeLabel":"string"},"cycle_time":{"type":"string","format":"date-time","description":"Echoed from the request.","example":"2026-09-29T02:05:00+09:00","pattern":"^\\d{4}-\\d{2}-\\d{2}[Tt]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:[Zz]|[+-]\\d{2}:\\d{2})$","isRequired":true,"uniqueKey":"cycle_time","typeLabel":"string\u003cdate-time>"},"received_at":{"type":"string","format":"date-time","description":"First valid receipt of this cycle ID, preserved across failed inference retries and completed replays.","example":"2026-09-29T02:05:03+09:00","pattern":"^\\d{4}-\\d{2}-\\d{2}[Tt]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:[Zz]|[+-]\\d{2}:\\d{2})$","isRequired":true,"uniqueKey":"received_at","typeLabel":"string\u003cdate-time>"},"scored_at":{"type":"string","format":"date-time","description":"Actual scoring completion time sampled after the full inference batch. Measure client receipt time separately.","example":"2026-09-29T02:05:09+09:00","pattern":"^\\d{4}-\\d{2}-\\d{2}[Tt]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:[Zz]|[+-]\\d{2}:\\d{2})$","isRequired":true,"uniqueKey":"scored_at","typeLabel":"string\u003cdate-time>"},"model_version":{"type":"string","example":"model0924-downvote0","description":"Version reported by the actual loaded Model 0924 adapter and configured down-vote coefficient. No environment-only label override or proxy scorer is used.","isRequired":true,"uniqueKey":"model_version","typeLabel":"string"},"weights_version":{"type":"string","example":"w0924-downvote0","description":"Weights that actually produced this cycle's scores. Verify that refreshed scores and their version match; do not relabel cached scores.","isRequired":true,"uniqueKey":"weights_version","typeLabel":"string"},"counts":{"type":"object","properties":{"candidates":{"type":"integer","minimum":0,"example":1,"description":"Candidate identities first accepted in this cycle, excluding repeat deliveries. Group unique entrants by original extracted_at KST date for daily reconciliation.","isRequired":true,"uniqueKey":"counts.candidates","typeLabel":"integer"},"engagement":{"type":"integer","minimum":0,"example":2,"description":"Rows received in `engagement`.","isRequired":true,"uniqueKey":"counts.engagement","typeLabel":"integer"},"candidate_scores":{"type":"integer","minimum":0,"example":1,"description":"Rows received in `candidate_scores`.","isRequired":true,"uniqueKey":"counts.candidate_scores","typeLabel":"integer"},"removals":{"type":"integer","minimum":0,"example":1,"description":"Removal identities first accepted in this cycle, excluding repeats. Counts receipt, not original decided_at events or client-side operator labels. Under the operator-independent sender policy, saved/hidden decisions do not produce removal receipts.","isRequired":true,"uniqueKey":"counts.removals","typeLabel":"integer"},"scored_now":{"type":"integer","minimum":0,"example":1,"description":"Scoring events in this cycle, including rescoring; not unique first scores or a first-score SLA denominator.","isRequired":true,"uniqueKey":"counts.scored_now","typeLabel":"integer"},"waiting":{"type":"integer","minimum":0,"example":1,"description":"Results with status `waiting`.","isRequired":true,"uniqueKey":"counts.waiting","typeLabel":"integer"},"not_scored":{"type":"integer","minimum":0,"example":0,"description":"Results with status `not_scored`.","isRequired":true,"uniqueKey":"counts.not_scored","typeLabel":"integer"},"results":{"type":"integer","minimum":0,"example":2,"description":"Rows in results for this cycle. Under the proposed refresh policy this includes newly computed scores for pending posts; historical replay stays unchanged.","isRequired":true,"uniqueKey":"counts.results","typeLabel":"integer"}},"required":["candidates","engagement","candidate_scores","removals","scored_now","waiting","not_scored","results"],"description":"Row counts for this cycle.","isRequired":true,"uniqueKey":"counts","typeLabel":"object"},"missing_feature_share":{"type":"number","minimum":0,"maximum":1,"example":0.11,"description":"Fraction of missing request counter fields. This does not count missing values across the model feature set and is not a rehearsal acceptance metric.","isRequired":true,"uniqueKey":"missing_feature_share","typeLabel":"number"},"warnings":{"type":"array","items":{"type":"string","uniqueKey":"warnings.items.[INDEX]","typeLabel":"string"},"example":[],"description":"Implementation warnings. Unknown fields are not guaranteed to be listed. An empty list does not prove model or data readiness.","isRequired":true,"uniqueKey":"warnings","typeLabel":"string[]"},"results":{"type":"array","items":{"type":"object","properties":{"gall_id":{"type":"string","minLength":1,"description":"Post key, together with `post_no`.","example":"example_gallery","isRequired":true,"uniqueKey":"results.items.[INDEX].gall_id","typeLabel":"string"},"post_no":{"type":"integer","minimum":1,"description":"Post number. Unique only within a gallery, so a post is always keyed by `gall_id` and `post_no` together.","example":31900001,"isRequired":true,"uniqueKey":"results.items.[INDEX].post_no","typeLabel":"integer"},"status":{"type":"string","enum":["scored","waiting","not_scored"],"example":"scored","description":"scored: eligible after queue entry plus 15 minutes and a usable score is present. waiting: before that mark; due_cycle is the first eligible boundary. not_scored: inspect reason, including missing_clock for unknown queue entry.","isRequired":true,"uniqueKey":"results.items.[INDEX].status","typeLabel":"enum\u003cstring>"},"score":{"oneOf":[{"type":"number","example":0.62,"description":"Final score from the verified delivered Model 0924: p_views minus the configured non-negative coefficient times downvote_share. Initially the coefficient is zero. Scores can be negative; do not clip them. Null unless scored.","uniqueKey":"results.items.[INDEX].score.oneOf.0","typeLabel":"number"},{"type":"null","example":0.62,"description":"Final score from the verified delivered Model 0924: p_views minus the configured non-negative coefficient times downvote_share. Initially the coefficient is zero. Scores can be negative; do not clip them. Null unless scored.","uniqueKey":"results.items.[INDEX].score.oneOf.1","typeLabel":"null"}],"uniqueKey":"results.items.[INDEX].score","typeLabel":"number | null"},"p_views":{"oneOf":[{"type":"number","minimum":0,"maximum":1,"example":0.62,"description":"Optional views-head prediction from the real model; the intended target is top-quarter board views within the delivered tier/day/time grouping. Omit or use null when unavailable; not required for client-side final-score computation.","uniqueKey":"results.items.[INDEX].p_views.oneOf.0","typeLabel":"number"},{"type":"null","minimum":0,"maximum":1,"example":0.62,"description":"Optional views-head prediction from the real model; the intended target is top-quarter board views within the delivered tier/day/time grouping. Omit or use null when unavailable; not required for client-side final-score computation.","uniqueKey":"results.items.[INDEX].p_views.oneOf.1","typeLabel":"null"}],"uniqueKey":"results.items.[INDEX].p_views","typeLabel":"number | null"},"p_comments":{"oneOf":[{"type":"number","minimum":0,"maximum":1,"example":null,"description":"Legacy optional head, unavailable in the delivered Model 0924. The runtime returns null and does not fabricate a prediction.","deprecated":true,"uniqueKey":"results.items.[INDEX].p_comments.oneOf.0","typeLabel":"number"},{"type":"null","minimum":0,"maximum":1,"example":null,"description":"Legacy optional head, unavailable in the delivered Model 0924. The runtime returns null and does not fabricate a prediction.","deprecated":true,"uniqueKey":"results.items.[INDEX].p_comments.oneOf.1","typeLabel":"null"}],"uniqueKey":"results.items.[INDEX].p_comments","typeLabel":"number | null"},"p_up":{"oneOf":[{"type":"number","minimum":0,"maximum":1,"example":null,"description":"Legacy optional head, unavailable in the delivered Model 0924. The runtime returns null and does not fabricate a prediction.","deprecated":true,"uniqueKey":"results.items.[INDEX].p_up.oneOf.0","typeLabel":"number"},{"type":"null","minimum":0,"maximum":1,"example":null,"description":"Legacy optional head, unavailable in the delivered Model 0924. The runtime returns null and does not fabricate a prediction.","deprecated":true,"uniqueKey":"results.items.[INDEX].p_up.oneOf.1","typeLabel":"null"}],"uniqueKey":"results.items.[INDEX].p_up","typeLabel":"number | null"},"downvote_share":{"oneOf":[{"type":"number","minimum":0,"maximum":1,"example":0.08,"description":"Optional predicted down-vote share from the real model. The initial down-vote penalty weight is 0. Omit or use null when unavailable; not required for client-side final-score computation.","uniqueKey":"results.items.[INDEX].downvote_share.oneOf.0","typeLabel":"number"},{"type":"null","minimum":0,"maximum":1,"example":0.08,"description":"Optional predicted down-vote share from the real model. The initial down-vote penalty weight is 0. Omit or use null when unavailable; not required for client-side final-score computation.","uniqueKey":"results.items.[INDEX].downvote_share.oneOf.1","typeLabel":"null"}],"uniqueKey":"results.items.[INDEX].downvote_share","typeLabel":"number | null"},"scored_at_cycle":{"type":"string","format":"date-time","description":"Cycle that produced this row score. Under the proposed refresh policy it advances when the pending post is re-scored in a new cycle; replay of the same completed cycle preserves the original value.","example":"2026-09-29T02:05:00+09:00","pattern":"^\\d{4}-\\d{2}-\\d{2}[Tt]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:[Zz]|[+-]\\d{2}:\\d{2})$","uniqueKey":"results.items.[INDEX].scored_at_cycle","typeLabel":"string\u003cdate-time>"},"due_cycle":{"oneOf":[{"type":"string","format":"date-time","description":"For waiting results, the first scheduled cycle boundary at or after extracted_at plus 15 minutes. Null/absent for scored results.","pattern":"^\\d{4}-\\d{2}-\\d{2}[Tt]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:[Zz]|[+-]\\d{2}:\\d{2})$","uniqueKey":"results.items.[INDEX].due_cycle.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","description":"For waiting results, the first scheduled cycle boundary at or after extracted_at plus 15 minutes. Null/absent for scored results.","pattern":"^\\d{4}-\\d{2}-\\d{2}[Tt]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:[Zz]|[+-]\\d{2}:\\d{2})$","uniqueKey":"results.items.[INDEX].due_cycle.oneOf.1","typeLabel":"null"}],"uniqueKey":"results.items.[INDEX].due_cycle","typeLabel":"string\u003cdate-time> | null"},"reason":{"type":"string","enum":["missing_title","missing_clock","post_unavailable","unknown_post"],"example":"post_unavailable","description":"Present when not_scored. post_unavailable means latest engagement status is missing or nomap; unknown_post means engagement arrived without a candidate; missing_clock means extracted_at is unknown and the 15-minute eligibility point cannot be established. missing_title remains a legacy value; empty titles alone do not prevent scoring.","uniqueKey":"results.items.[INDEX].reason","typeLabel":"enum\u003cstring>"}},"required":["gall_id","post_no","status"],"description":"The state of one pending post.","uniqueKey":"results.items.[INDEX]","typeLabel":"object"},"description":"One result per pending candidate under the proposed refresh policy. Scores may change across new cycles; replay of a completed cycle is unchanged. Removed posts are absent from subsequent cycles.","isRequired":true,"uniqueKey":"results","typeLabel":"object[]"},"deduplication":{"oneOf":[{"type":"object","title":"DeduplicationReport","description":"Persisted LLM same-event rankings and honest unchecked coverage for main/light. Every raw score remains in results. Omitted for legacy completed cycles. Partial/unavailable completed reports remain immutable on POST replay and GET.","required":["status","model","prompt_version","tiers"],"properties":{"status":{"enum":["completed","partial","unavailable","disabled"],"title":"Status","type":"string","isRequired":true,"uniqueKey":"deduplication.oneOf.0.status","typeLabel":"enum\u003cstring>"},"model":{"oneOf":[{"title":"Model","type":"string","isRequired":true,"uniqueKey":"deduplication.oneOf.0.model.oneOf.0","typeLabel":"string"},{"title":"Model","type":"null","isRequired":true,"uniqueKey":"deduplication.oneOf.0.model.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"deduplication.oneOf.0.model","typeLabel":"string | null"},"prompt_version":{"oneOf":[{"title":"Prompt Version","type":"string","isRequired":true,"uniqueKey":"deduplication.oneOf.0.prompt_version.oneOf.0","typeLabel":"string"},{"title":"Prompt Version","type":"null","isRequired":true,"uniqueKey":"deduplication.oneOf.0.prompt_version.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"deduplication.oneOf.0.prompt_version","typeLabel":"string | null"},"tiers":{"additionalProperties":false,"properties":{"main":{"additionalProperties":false,"description":"Published-window assessment with confirmed-duplicate-only exclusion.\n\nFor newly finalized cycles, ranked and duplicates partition scored candidates.\nUnchecked is a diagnostic subset of ranked, not another exclusion list.\nEligibility does not certify uniqueness; unknown, unfinished and unavailable\nassessments remain eligible. Candidate-to-candidate checks are not performed.\nMain and Light eligibility are independent; raw score rows are unchanged.\nHistorical completed responses retain their original ranking policy.","properties":{"status":{"enum":["completed","partial","unavailable","disabled"],"title":"Status","type":"string","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.main.status","typeLabel":"enum\u003cstring>"},"context":{"description":"published_window means a snapshot was supplied. candidate_only is the legacy wire label for missing context; new cycles do not perform candidate-only deduplication. Missing context leaves scored candidates ranked and unchecked without certifying uniqueness.","enum":["published_window","candidate_only"],"title":"Context","type":"string","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.main.context","typeLabel":"enum\u003cstring>"},"ranked":{"description":"All scored candidates except confirmed duplicates in this tier, descending raw score then gall_id/post_no. Includes unchecked candidates even when assessment is partial, unavailable or disabled; eligibility is not proof of uniqueness. Unchecked is an overlapping diagnostic subset and must not be subtracted for selection. No candidate-to-candidate checks or selection quota. Historical completed responses retain their original checked-only rankings.","items":{"additionalProperties":false,"properties":{"gall_id":{"title":"Gall Id","type":"string","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.main.ranked.items.[INDEX].gall_id","typeLabel":"string"},"post_no":{"title":"Post No","type":"integer","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.main.ranked.items.[INDEX].post_no","typeLabel":"integer"}},"required":["gall_id","post_no"],"title":"PostReference","type":"object","uniqueKey":"deduplication.oneOf.0.tiers.main.ranked.items.[INDEX]","typeLabel":"PostReference · object"},"title":"Ranked","type":"array","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.main.ranked","typeLabel":"PostReference · object[]"},"duplicates":{"items":{"additionalProperties":false,"properties":{"gall_id":{"title":"Gall Id","type":"string","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.main.duplicates.items.[INDEX].gall_id","typeLabel":"string"},"post_no":{"title":"Post No","type":"integer","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.main.duplicates.items.[INDEX].post_no","typeLabel":"integer"},"duplicate_of":{"type":"object","title":"PostReference","description":"For new cycles, one confirmed matching post in this tier's supplied window, not an exhaustive match list. Historical responses may reference a higher-ranked candidate.","required":["gall_id","post_no"],"properties":{"gall_id":{"title":"Gall Id","type":"string","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.main.duplicates.items.[INDEX].duplicate_of.gall_id","typeLabel":"string"},"post_no":{"title":"Post No","type":"integer","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.main.duplicates.items.[INDEX].duplicate_of.post_no","typeLabel":"integer"}},"additionalProperties":false,"isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.main.duplicates.items.[INDEX].duplicate_of","typeLabel":"PostReference · object"},"reason":{"description":"New cycles use same_event_published only. same_event_candidate remains accepted for immutable historical responses from the previous algorithm.","enum":["same_event_candidate","same_event_published"],"title":"Reason","type":"string","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.main.duplicates.items.[INDEX].reason","typeLabel":"enum\u003cstring>"}},"required":["gall_id","post_no","duplicate_of","reason"],"title":"DuplicateDecision","type":"object","uniqueKey":"deduplication.oneOf.0.tiers.main.duplicates.items.[INDEX]","typeLabel":"DuplicateDecision · object"},"title":"Duplicates","type":"array","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.main.duplicates","typeLabel":"DuplicateDecision · object[]"},"unchecked":{"description":"Diagnostic subset of ranked whose required comparisons are unfinished, unknown or unavailable. These candidates remain eligible under confirmed-duplicate-only exclusion, but are not certified unique. Do not exclude them solely for this status. Historical completed responses retain their original disjoint lists.","items":{"additionalProperties":false,"properties":{"gall_id":{"title":"Gall Id","type":"string","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.main.unchecked.items.[INDEX].gall_id","typeLabel":"string"},"post_no":{"title":"Post No","type":"integer","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.main.unchecked.items.[INDEX].post_no","typeLabel":"integer"}},"required":["gall_id","post_no"],"title":"PostReference","type":"object","uniqueKey":"deduplication.oneOf.0.tiers.main.unchecked.items.[INDEX]","typeLabel":"PostReference · object"},"title":"Unchecked","type":"array","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.main.unchecked","typeLabel":"PostReference · object[]"},"warnings":{"description":"Includes published_window_missing for absent context, published_content_missing for a supplied post with no delivered text or image evidence, and background_pending for incomplete assessment. Retained full-evidence unknowns stay unchecked without another call until their evidence/model/prompt changes. Bootstrap content can be supplied on a new cycle; worker provider failures are separate operational diagnostics.","items":{"type":"string","uniqueKey":"deduplication.oneOf.0.tiers.main.warnings.items.[INDEX]","typeLabel":"string"},"title":"Warnings","type":"array","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.main.warnings","typeLabel":"string[]"}},"required":["status","context","ranked","duplicates","unchecked","warnings"],"title":"TierDeduplication","type":"object","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.main","typeLabel":"TierDeduplication · object"},"light":{"additionalProperties":false,"description":"Published-window assessment with confirmed-duplicate-only exclusion.\n\nFor newly finalized cycles, ranked and duplicates partition scored candidates.\nUnchecked is a diagnostic subset of ranked, not another exclusion list.\nEligibility does not certify uniqueness; unknown, unfinished and unavailable\nassessments remain eligible. Candidate-to-candidate checks are not performed.\nMain and Light eligibility are independent; raw score rows are unchanged.\nHistorical completed responses retain their original ranking policy.","properties":{"status":{"enum":["completed","partial","unavailable","disabled"],"title":"Status","type":"string","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.light.status","typeLabel":"enum\u003cstring>"},"context":{"description":"published_window means a snapshot was supplied. candidate_only is the legacy wire label for missing context; new cycles do not perform candidate-only deduplication. Missing context leaves scored candidates ranked and unchecked without certifying uniqueness.","enum":["published_window","candidate_only"],"title":"Context","type":"string","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.light.context","typeLabel":"enum\u003cstring>"},"ranked":{"description":"All scored candidates except confirmed duplicates in this tier, descending raw score then gall_id/post_no. Includes unchecked candidates even when assessment is partial, unavailable or disabled; eligibility is not proof of uniqueness. Unchecked is an overlapping diagnostic subset and must not be subtracted for selection. No candidate-to-candidate checks or selection quota. Historical completed responses retain their original checked-only rankings.","items":{"additionalProperties":false,"properties":{"gall_id":{"title":"Gall Id","type":"string","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.light.ranked.items.[INDEX].gall_id","typeLabel":"string"},"post_no":{"title":"Post No","type":"integer","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.light.ranked.items.[INDEX].post_no","typeLabel":"integer"}},"required":["gall_id","post_no"],"title":"PostReference","type":"object","uniqueKey":"deduplication.oneOf.0.tiers.light.ranked.items.[INDEX]","typeLabel":"PostReference · object"},"title":"Ranked","type":"array","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.light.ranked","typeLabel":"PostReference · object[]"},"duplicates":{"items":{"additionalProperties":false,"properties":{"gall_id":{"title":"Gall Id","type":"string","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.light.duplicates.items.[INDEX].gall_id","typeLabel":"string"},"post_no":{"title":"Post No","type":"integer","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.light.duplicates.items.[INDEX].post_no","typeLabel":"integer"},"duplicate_of":{"type":"object","title":"PostReference","description":"For new cycles, one confirmed matching post in this tier's supplied window, not an exhaustive match list. Historical responses may reference a higher-ranked candidate.","required":["gall_id","post_no"],"properties":{"gall_id":{"title":"Gall Id","type":"string","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.light.duplicates.items.[INDEX].duplicate_of.gall_id","typeLabel":"string"},"post_no":{"title":"Post No","type":"integer","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.light.duplicates.items.[INDEX].duplicate_of.post_no","typeLabel":"integer"}},"additionalProperties":false,"isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.light.duplicates.items.[INDEX].duplicate_of","typeLabel":"PostReference · object"},"reason":{"description":"New cycles use same_event_published only. same_event_candidate remains accepted for immutable historical responses from the previous algorithm.","enum":["same_event_candidate","same_event_published"],"title":"Reason","type":"string","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.light.duplicates.items.[INDEX].reason","typeLabel":"enum\u003cstring>"}},"required":["gall_id","post_no","duplicate_of","reason"],"title":"DuplicateDecision","type":"object","uniqueKey":"deduplication.oneOf.0.tiers.light.duplicates.items.[INDEX]","typeLabel":"DuplicateDecision · object"},"title":"Duplicates","type":"array","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.light.duplicates","typeLabel":"DuplicateDecision · object[]"},"unchecked":{"description":"Diagnostic subset of ranked whose required comparisons are unfinished, unknown or unavailable. These candidates remain eligible under confirmed-duplicate-only exclusion, but are not certified unique. Do not exclude them solely for this status. Historical completed responses retain their original disjoint lists.","items":{"additionalProperties":false,"properties":{"gall_id":{"title":"Gall Id","type":"string","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.light.unchecked.items.[INDEX].gall_id","typeLabel":"string"},"post_no":{"title":"Post No","type":"integer","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.light.unchecked.items.[INDEX].post_no","typeLabel":"integer"}},"required":["gall_id","post_no"],"title":"PostReference","type":"object","uniqueKey":"deduplication.oneOf.0.tiers.light.unchecked.items.[INDEX]","typeLabel":"PostReference · object"},"title":"Unchecked","type":"array","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.light.unchecked","typeLabel":"PostReference · object[]"},"warnings":{"description":"Includes published_window_missing for absent context, published_content_missing for a supplied post with no delivered text or image evidence, and background_pending for incomplete assessment. Retained full-evidence unknowns stay unchecked without another call until their evidence/model/prompt changes. Bootstrap content can be supplied on a new cycle; worker provider failures are separate operational diagnostics.","items":{"type":"string","uniqueKey":"deduplication.oneOf.0.tiers.light.warnings.items.[INDEX]","typeLabel":"string"},"title":"Warnings","type":"array","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.light.warnings","typeLabel":"string[]"}},"required":["status","context","ranked","duplicates","unchecked","warnings"],"title":"TierDeduplication","type":"object","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers.light","typeLabel":"TierDeduplication · object"}},"required":["main","light"],"title":"DeduplicationTiers","type":"object","isRequired":true,"uniqueKey":"deduplication.oneOf.0.tiers","typeLabel":"DeduplicationTiers · object"},"coverage":{"oneOf":[{"type":"object","title":"DedupCoverage","required":["total_candidates","comparisons_total","comparisons_checked","provider_calls","cache_hits","elapsed_ms"],"properties":{"total_candidates":{"minimum":0,"title":"Total Candidates","type":"integer","isRequired":true,"uniqueKey":"deduplication.oneOf.0.coverage.oneOf.0.total_candidates","typeLabel":"integer"},"comparisons_total":{"description":"Theoretical unique candidate-to-published semantic pairs across both tier windows. Shared pairs count once; same-post identities are excluded. A positive match may make other pairs unnecessary without counting them as checked. No candidate-to-candidate pairs.","minimum":0,"title":"Comparisons Total","type":"integer","isRequired":true,"uniqueKey":"deduplication.oneOf.0.coverage.oneOf.0.comparisons_total","typeLabel":"integer"},"comparisons_checked":{"description":"Required pairs covered by validated same/different facts used in this frozen cycle report, including facts completed during its bounded wait. Progress after finalization is reflected only in a new cycle. Unknown or failed comparisons are not checked.","minimum":0,"title":"Comparisons Checked","type":"integer","isRequired":true,"uniqueKey":"deduplication.oneOf.0.coverage.oneOf.0.comparisons_checked","typeLabel":"integer"},"provider_calls":{"description":"Provider calls initiated by the foreground report path; zero with background processing. Worker calls may overlap the HTTP wait and are recorded separately. Historical completed responses retain their original values.","minimum":0,"title":"Provider Calls","type":"integer","isRequired":true,"uniqueKey":"deduplication.oneOf.0.coverage.oneOf.0.provider_calls","typeLabel":"integer"},"cache_hits":{"description":"Unique required same/different semantic pair verdicts reused from the durable pair cache in this frozen cycle report, not unknown verdicts or cumulative background progress. Historical reports from the previous algorithm counted cached batches instead.","minimum":0,"title":"Cache Hits","type":"integer","isRequired":true,"uniqueKey":"deduplication.oneOf.0.coverage.oneOf.0.cache_hits","typeLabel":"integer"},"elapsed_ms":{"description":"Wall time for this cycle's deduplication assessment, including its bounded background-progress wait when performed. Excludes preceding raw scoring; not provider inference alone or client round-trip time.","minimum":0,"title":"Elapsed Ms","type":"number","isRequired":true,"uniqueKey":"deduplication.oneOf.0.coverage.oneOf.0.elapsed_ms","typeLabel":"number"}},"additionalProperties":false,"uniqueKey":"deduplication.oneOf.0.coverage.oneOf.0","typeLabel":"DedupCoverage · object"},{"type":"null","uniqueKey":"deduplication.oneOf.0.coverage.oneOf.1","typeLabel":"null"}],"uniqueKey":"deduplication.oneOf.0.coverage","typeLabel":"DedupCoverage · object | null"}},"additionalProperties":false,"uniqueKey":"deduplication.oneOf.0","typeLabel":"DeduplicationReport · object"},{"type":"null","uniqueKey":"deduplication.oneOf.1","typeLabel":"null"}],"uniqueKey":"deduplication","typeLabel":"DeduplicationReport · object | null"}},"required":["cycle_id","cycle_time","received_at","scored_at","model_version","weights_version","counts","missing_feature_share","warnings","results"],"uniqueKey":"","typeLabel":"object"},"examples":{"first_scores":{"title":"first_scores","value":{"cycle_id":"20260929T0205","cycle_time":"2026-09-29T02:05:00+09:00","received_at":"2026-09-29T02:05:03+09:00","scored_at":"2026-09-29T02:05:09+09:00","model_version":"m0924-weight0","weights_version":"w-1","counts":{"candidates":1,"engagement":2,"candidate_scores":1,"removals":1,"scored_now":2,"waiting":0,"not_scored":0,"results":2},"missing_feature_share":0.11,"warnings":[],"results":[{"gall_id":"example_gallery","post_no":31899120,"status":"scored","score":0.62,"scored_at_cycle":"2026-09-29T02:05:00+09:00"},{"gall_id":"example_gallery","post_no":31900001,"status":"scored","score":0.51,"scored_at_cycle":"2026-09-29T02:05:00+09:00"}],"deduplication":{"status":"unavailable","model":null,"prompt_version":null,"tiers":{"main":{"status":"unavailable","context":"candidate_only","ranked":[{"gall_id":"example_gallery","post_no":31899120},{"gall_id":"example_gallery","post_no":31900001}],"duplicates":[],"unchecked":[{"gall_id":"example_gallery","post_no":31899120},{"gall_id":"example_gallery","post_no":31900001}],"warnings":["provider_not_configured","published_window_missing"]},"light":{"status":"unavailable","context":"candidate_only","ranked":[{"gall_id":"example_gallery","post_no":31899120},{"gall_id":"example_gallery","post_no":31900001}],"duplicates":[],"unchecked":[{"gall_id":"example_gallery","post_no":31899120},{"gall_id":"example_gallery","post_no":31900001}],"warnings":["provider_not_configured","published_window_missing"]}}}}},"refreshed_and_not_scored":{"title":"refreshed_and_not_scored","value":{"cycle_id":"20260929T0210","cycle_time":"2026-09-29T02:10:00+09:00","received_at":"2026-09-29T02:10:02+09:00","scored_at":"2026-09-29T02:10:03+09:00","model_version":"m0924-weight0","weights_version":"w-1","counts":{"candidates":1,"engagement":3,"candidate_scores":3,"removals":0,"scored_now":2,"waiting":0,"not_scored":1,"results":3},"missing_feature_share":0,"warnings":[],"results":[{"gall_id":"example_gallery","post_no":31899120,"status":"scored","score":0.67,"scored_at_cycle":"2026-09-29T02:10:00+09:00"},{"gall_id":"example_gallery","post_no":31900001,"status":"scored","score":0.56,"scored_at_cycle":"2026-09-29T02:10:00+09:00"},{"gall_id":"example_gallery","post_no":31900044,"status":"not_scored","score":null,"reason":"missing_clock"}],"deduplication":{"status":"unavailable","model":null,"prompt_version":null,"tiers":{"main":{"status":"unavailable","context":"candidate_only","ranked":[{"gall_id":"example_gallery","post_no":31899120},{"gall_id":"example_gallery","post_no":31900001}],"duplicates":[],"unchecked":[{"gall_id":"example_gallery","post_no":31899120},{"gall_id":"example_gallery","post_no":31900001}],"warnings":["provider_not_configured","published_window_missing"]},"light":{"status":"unavailable","context":"candidate_only","ranked":[{"gall_id":"example_gallery","post_no":31899120},{"gall_id":"example_gallery","post_no":31900001}],"duplicates":[],"unchecked":[{"gall_id":"example_gallery","post_no":31899120},{"gall_id":"example_gallery","post_no":31900001}],"warnings":["provider_not_configured","published_window_missing"]}}}}},"waiting_before_fifteen_minutes":{"title":"waiting_before_fifteen_minutes","value":{"cycle_id":"20260929T0205","cycle_time":"2026-09-29T02:05:00+09:00","received_at":"2026-09-29T02:05:03+09:00","scored_at":"2026-09-29T02:05:09+09:00","model_version":"m0924-weight0","weights_version":"w-1","counts":{"candidates":1,"engagement":2,"candidate_scores":1,"removals":1,"scored_now":1,"waiting":1,"not_scored":0,"results":2},"missing_feature_share":0.11,"warnings":[],"results":[{"gall_id":"example_gallery","post_no":31899120,"status":"scored","score":0.62,"scored_at_cycle":"2026-09-29T02:05:00+09:00"},{"gall_id":"example_gallery","post_no":31900001,"status":"waiting","due_cycle":"2026-09-29T02:20:00+09:00"}],"deduplication":{"status":"unavailable","model":null,"prompt_version":null,"tiers":{"main":{"status":"unavailable","context":"candidate_only","ranked":[{"gall_id":"example_gallery","post_no":31899120}],"duplicates":[],"unchecked":[{"gall_id":"example_gallery","post_no":31899120}],"warnings":["provider_not_configured","published_window_missing"]},"light":{"status":"unavailable","context":"candidate_only","ranked":[{"gall_id":"example_gallery","post_no":31899120}],"duplicates":[],"unchecked":[{"gall_id":"example_gallery","post_no":31899120}],"warnings":["provider_not_configured","published_window_missing"]}}}}}},"exampleType":"examples"}},"exampleType":"examples"},"e4e831b2-fc68-4b08-bd69-531b883416bf":{"description":"Malformed JSON or a request-schema failure. Semantic checks may return only the first error; no exhaustive-error guarantee.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"bad_request","description":"Machine-readable code. See Errors.","isRequired":true,"uniqueKey":"error.code","typeLabel":"string"},"message":{"type":"string","example":"2 fields failed validation","description":"Human-readable summary.","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","example":"candidates[0].created_at","description":"Path of the failing field.","isRequired":true,"uniqueKey":"error.fields.items.[INDEX].path","typeLabel":"string"},"problem":{"type":"string","example":"timestamp must include an explicit offset","description":"Description of the validation failure.","isRequired":true,"uniqueKey":"error.fields.items.[INDEX].problem","typeLabel":"string"}},"required":["path","problem"],"uniqueKey":"error.fields.items.[INDEX]","typeLabel":"object"},"description":"Every failing field, when the error is about the body.","uniqueKey":"error.fields","typeLabel":"object[]"}},"required":["code","message"],"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"bad_request","message":"2 fields failed validation","fields":[{"path":"candidates[0].created_at","problem":"timestamp must include an explicit offset"},{"path":"engagement[3].views","problem":"must be a non-negative integer or null"}]}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"bad_request","message":"2 fields failed validation","fields":[{"path":"candidates[0].created_at","problem":"timestamp must include an explicit offset"},{"path":"engagement[3].views","problem":"must be a non-negative integer or null"}]}}}},"exampleType":"examples"}},"exampleType":"examples"},"0891eae5-1684-435e-b21e-2e3c989b9d32":{"description":"The API key is missing or unknown.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"bad_request","description":"Machine-readable code. See Errors.","isRequired":true,"uniqueKey":"error.code","typeLabel":"string"},"message":{"type":"string","example":"2 fields failed validation","description":"Human-readable summary.","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","example":"candidates[0].created_at","description":"Path of the failing field.","isRequired":true,"uniqueKey":"error.fields.items.[INDEX].path","typeLabel":"string"},"problem":{"type":"string","example":"timestamp must include an explicit offset","description":"Description of the validation failure.","isRequired":true,"uniqueKey":"error.fields.items.[INDEX].problem","typeLabel":"string"}},"required":["path","problem"],"uniqueKey":"error.fields.items.[INDEX]","typeLabel":"object"},"description":"Every failing field, when the error is about the body.","uniqueKey":"error.fields","typeLabel":"object[]"}},"required":["code","message"],"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"unauthorized","message":"API key missing or unknown"}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"unauthorized","message":"API key missing or unknown"}}}},"exampleType":"examples"}},"exampleType":"examples"},"c6980715-f405-45e3-bc4e-727ceaca5790":{"description":"The id was already used with a different body. The first body stays.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"bad_request","description":"Machine-readable code. See Errors.","isRequired":true,"uniqueKey":"error.code","typeLabel":"string"},"message":{"type":"string","example":"2 fields failed validation","description":"Human-readable summary.","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","example":"candidates[0].created_at","description":"Path of the failing field.","isRequired":true,"uniqueKey":"error.fields.items.[INDEX].path","typeLabel":"string"},"problem":{"type":"string","example":"timestamp must include an explicit offset","description":"Description of the validation failure.","isRequired":true,"uniqueKey":"error.fields.items.[INDEX].problem","typeLabel":"string"}},"required":["path","problem"],"uniqueKey":"error.fields.items.[INDEX]","typeLabel":"object"},"description":"Every failing field, when the error is about the body.","uniqueKey":"error.fields","typeLabel":"object[]"}},"required":["code","message"],"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"cycle_conflict","message":"cycle 20260929T0205 was already received with a different body"}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"cycle_conflict","message":"cycle 20260929T0205 was already received with a different body"}}}},"exampleType":"examples"}},"exampleType":"examples"},"2251b32f-7f08-4e76-8481-019e228dbe3d":{"description":"Current implementation size protection: 16 MiB JSON after decompression or 5 MiB per image. These are engineering protections, not agreed client quotas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"bad_request","description":"Machine-readable code. See Errors.","isRequired":true,"uniqueKey":"error.code","typeLabel":"string"},"message":{"type":"string","example":"2 fields failed validation","description":"Human-readable summary.","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","example":"candidates[0].created_at","description":"Path of the failing field.","isRequired":true,"uniqueKey":"error.fields.items.[INDEX].path","typeLabel":"string"},"problem":{"type":"string","example":"timestamp must include an explicit offset","description":"Description of the validation failure.","isRequired":true,"uniqueKey":"error.fields.items.[INDEX].problem","typeLabel":"string"}},"required":["path","problem"],"uniqueKey":"error.fields.items.[INDEX]","typeLabel":"object"},"description":"Every failing field, when the error is about the body.","uniqueKey":"error.fields","typeLabel":"object[]"}},"required":["code","message"],"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"too_large","message":"JSON body exceeds 16 MiB after decompression"}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"too_large","message":"JSON body exceeds 16 MiB after decompression"}}}},"exampleType":"examples"}},"exampleType":"examples"},"6b502312-5013-4526-bd97-428710060e45":{"description":"The body is valid JSON and matches the schema, but the values are not acceptable. Nothing is stored.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"bad_request","description":"Machine-readable code. See Errors.","isRequired":true,"uniqueKey":"error.code","typeLabel":"string"},"message":{"type":"string","example":"2 fields failed validation","description":"Human-readable summary.","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","example":"candidates[0].created_at","description":"Path of the failing field.","isRequired":true,"uniqueKey":"error.fields.items.[INDEX].path","typeLabel":"string"},"problem":{"type":"string","example":"timestamp must include an explicit offset","description":"Description of the validation failure.","isRequired":true,"uniqueKey":"error.fields.items.[INDEX].problem","typeLabel":"string"}},"required":["path","problem"],"uniqueKey":"error.fields.items.[INDEX]","typeLabel":"object"},"description":"Every failing field, when the error is about the body.","uniqueKey":"error.fields","typeLabel":"object[]"}},"required":["code","message"],"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"unprocessable","message":"cycle_time cannot be more than 60 seconds in the future","fields":[{"path":"cycle_time","problem":"must not exceed server time by more than 60 seconds"}]}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"unprocessable","message":"cycle_time cannot be more than 60 seconds in the future","fields":[{"path":"cycle_time","problem":"must not exceed server time by more than 60 seconds"}]}}}},"exampleType":"examples"}},"exampleType":"examples"},"4d839c58-b0d6-423f-8a07-89527ded35fa":{"description":"Server failure. Skip late or unusable scores for the decision cycle, preserve unacknowledged data and reconcile delivery. Alert delivery must be verified separately.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"bad_request","description":"Machine-readable code. See Errors.","isRequired":true,"uniqueKey":"error.code","typeLabel":"string"},"message":{"type":"string","example":"2 fields failed validation","description":"Human-readable summary.","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","example":"candidates[0].created_at","description":"Path of the failing field.","isRequired":true,"uniqueKey":"error.fields.items.[INDEX].path","typeLabel":"string"},"problem":{"type":"string","example":"timestamp must include an explicit offset","description":"Description of the validation failure.","isRequired":true,"uniqueKey":"error.fields.items.[INDEX].problem","typeLabel":"string"}},"required":["path","problem"],"uniqueKey":"error.fields.items.[INDEX]","typeLabel":"object"},"description":"Every failing field, when the error is about the body.","uniqueKey":"error.fields","typeLabel":"object[]"}},"required":["code","message"],"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"server_error","message":"internal error"}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"server_error","message":"internal error"}}}},"exampleType":"examples"}},"exampleType":"examples"},"a8e1c493-3983-4325-91d9-2265a4ad5281":{"description":"Server failure. Skip late or unusable scores for the decision cycle, preserve unacknowledged data and reconcile delivery. Alert delivery must be verified separately.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"bad_request","description":"Machine-readable code. See Errors.","isRequired":true,"uniqueKey":"error.code","typeLabel":"string"},"message":{"type":"string","example":"2 fields failed validation","description":"Human-readable summary.","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","example":"candidates[0].created_at","description":"Path of the failing field.","isRequired":true,"uniqueKey":"error.fields.items.[INDEX].path","typeLabel":"string"},"problem":{"type":"string","example":"timestamp must include an explicit offset","description":"Description of the validation failure.","isRequired":true,"uniqueKey":"error.fields.items.[INDEX].problem","typeLabel":"string"}},"required":["path","problem"],"uniqueKey":"error.fields.items.[INDEX]","typeLabel":"object"},"description":"Every failing field, when the error is about the body.","uniqueKey":"error.fields","typeLabel":"object[]"}},"required":["code","message"],"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"server_error","message":"internal error"}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"server_error","message":"internal error"}}}},"exampleType":"examples"}},"exampleType":"examples"}},"security":{"10858110-c05f-43f2-9504-99ddb0a1cf38":{"ApiKey":{"type":"apiKey","name":"Authorization","in":"header","description":"Proposed API key sent as the whole Authorization header value. One long-lived key, handed privately to the partner contact and rotated on either side's request. Per-endpoint scopes are not currently enforced.","scopes":[],"schemeName":"ApiKey"}}},"servers":{"d1723271-11ec-4bd0-a177-e7183babf553":{"url":"https://dcinside-rtb-api.stg.kr.ask.surf","description":"Planned rehearsal host. Cut over only after deployment and reachability verification; this specification does not declare the endpoint available."}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"apiKey","name":"Authorization","in":"header","description":"Proposed API key sent as the whole Authorization header value. One long-lived key, handed privately to the partner contact and rotated on either side's request. Per-endpoint scopes are not currently enforced.","scopes":[],"schemeName":"ApiKey"},"schema":{"title":"Authorization","type":"string","description":"Proposed API key sent as the whole Authorization header value. One long-lived key, handed privately to the partner contact and rotated on either side's request. Per-endpoint scopes are not currently enforced.","isRequired":true,"typeLabel":"string","deprecated":false},"schemeName":"ApiKey","name":"Authorization"}],"title":"ApiKey"}]},"originalFileLocation":"openapi.json"},"subdomain":"surfai-5f1034e6","siteName":"DCinside RTB API Documentation","title":"Score a Cycle - DCinside RTB API Documentation","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-13T15:33:18.848Z","originalFileLocation":"cycles.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Proposed rehearsal cycle payload and score response\">\u003cmeta data-mint-head name=\"application-name\" content=\"DCinside RTB API Documentation\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/surfai-5f1034e6/_generated/favicon/apple-touch-icon.png?v=3\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/surfai-5f1034e6/_generated/favicon/favicon-32x32.png?v=3\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/surfai-5f1034e6/_generated/favicon/favicon-16x16.png?v=3\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/surfai-5f1034e6/_generated/favicon/favicon.ico?v=3\">\u003cmeta data-mint-head property=\"og:title\" content=\"Score a Cycle - DCinside RTB API Documentation\">\u003cmeta data-mint-head property=\"og:description\" content=\"Proposed rehearsal cycle payload and score response\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"DCinside RTB API Documentation\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://surf-dcinside-api.kr.ask.surf/cycles\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://surfai-5f1034e6.mintlify.site/_mintlify/api/og/v2?division=Scoring+API\u0026amp;title=Score+a+Cycle\u0026amp;description=Proposed+rehearsal+cycle+payload+and+score+response\u0026amp;theme=21aace743e76edc6f913ef76\u0026amp;signature=4de526304b7a64c64dcc9f72aa7102b65935a468e824b348a017f650794becbd\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Score a Cycle - DCinside RTB API Documentation\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Proposed rehearsal cycle payload and score response\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://surfai-5f1034e6.mintlify.site/_mintlify/api/og/v2?division=Scoring+API\u0026amp;title=Score+a+Cycle\u0026amp;description=Proposed+rehearsal+cycle+payload+and+score+response\u0026amp;theme=21aace743e76edc6f913ef76\u0026amp;signature=4de526304b7a64c64dcc9f72aa7102b65935a468e824b348a017f650794becbd\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"https://mintlify.s3.us-west-1.amazonaws.com/surfai-5f1034e6/_generated/favicon/browserconfig.xml?v=3\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"DCinside RTB API Documentation\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#000000\">\u003clink data-mint-head rel=\"canonical\" href=\"https://surf-dcinside-api.kr.ask.surf/cycles\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/cycles.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://surf-dcinside-api.kr.ask.surf/#organization\",\"name\":\"DCinside RTB API Documentation\",\"url\":\"https://surf-dcinside-api.kr.ask.surf\"},{\"@type\":\"WebSite\",\"@id\":\"https://surf-dcinside-api.kr.ask.surf#website\",\"name\":\"DCinside RTB API Documentation\",\"url\":\"https://surf-dcinside-api.kr.ask.surf\",\"publisher\":{\"@id\":\"https://surf-dcinside-api.kr.ask.surf/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://surf-dcinside-api.kr.ask.surf/cycles#webpage\",\"url\":\"https://surf-dcinside-api.kr.ask.surf/cycles\",\"name\":\"Score a Cycle\",\"description\":\"Proposed rehearsal cycle payload and score response\",\"dateModified\":\"2026-10-13T15:33:18.848Z\",\"isPartOf\":{\"@id\":\"https://surf-dcinside-api.kr.ask.surf#website\"},\"breadcrumb\":{\"@id\":\"https://surf-dcinside-api.kr.ask.surf/cycles#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://surf-dcinside-api.kr.ask.surf/cycles#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"DCinside RTB API Documentation\",\"item\":\"https://surf-dcinside-api.kr.ask.surf\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Score a Cycle\",\"item\":\"https://surf-dcinside-api.kr.ask.surf/cycles\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://surf-dcinside-api.kr.ask.surf/cycles#apireference\",\"headline\":\"Score a Cycle\",\"name\":\"Score a Cycle\",\"description\":\"Proposed rehearsal cycle payload and score response\",\"url\":\"https://surf-dcinside-api.kr.ask.surf/cycles\",\"mainEntityOfPage\":{\"@id\":\"https://surf-dcinside-api.kr.ask.surf/cycles#webpage\"},\"dateModified\":\"2026-10-13T15:33:18.848Z\",\"publisher\":{\"@id\":\"https://surf-dcinside-api.kr.ask.surf/#organization\"},\"isPartOf\":{\"@id\":\"https://surf-dcinside-api.kr.ask.surf#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"DCinside RTB API Documentation\",\"publisher\":{\"@type\":\"Organization\",\"name\":\"DCinside RTB API Documentation\"},\"provider\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","agentPointerHref":"/cycles.md","siteName":"DCinside RTB API Documentation","nav":{"global":null,"groups":[{"group":"Getting Started","pages":[{"title":"Overview","href":"/overview"},{"title":"Conventions","href":"/conventions"},{"title":"How Scoring Works","href":"/scoring"},{"title":"Rehearsal and Acceptance","href":"/rollout"},{"title":"Errors and Recovery","description":"Current error handling, proposed recovery rules and rehearsal gaps","href":"/errors"}]},{"group":"Scoring API","pages":[{"title":"Score a Cycle","openapi":"openapi.json POST /v1/cycles","href":"/cycles"},{"title":"Retrieve Cycle Scores","description":"Recover the stored response for a specific cycle without scoring again","openapi":"openapi.json GET /v1/scores/{cycle_id}","href":"/scores"},{"title":"Event Deduplication","href":"/deduplication"},{"title":"Calling from the DCinside Worker","href":"/client"}]},{"group":"Images API","pages":[{"title":"Upload an Image","openapi":"openapi.json PUT /v1/images/{gall_id}/{post_no}/{NN}","href":"/images"}]},{"group":"Weights and Outcomes","tag":"Not in scope for trial","pages":[{"title":"Operator Outcomes","openapi":"openapi.json POST /v1/outcomes","href":"/outcomes"},{"title":"Set Weights","openapi":"openapi.json PUT /v1/weights","href":"/set-weights"},{"title":"Get Weights","openapi":"openapi.json GET /v1/weights","href":"/get-weights"}]},{"group":"Operations","pages":[{"title":"Health","openapi":"openapi.json GET /v1/health","href":"/health"}]}]},"basePath":"","title":"Score a Cycle - DCinside RTB API Documentation","buildId":"dpl_41S5Z2jG9QnfDRwN1KZrLdBwj7DM","deploymentId":"dpl_41S5Z2jG9QnfDRwN1KZrLdBwj7DM","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-DDP9JXtj.js","utils-8yQyvEtx.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-CBCFR8Sn.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-rQaXkUHa.js","snippetPresets-J5KpBTgV.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","conditional-requirements-CFM0id0Q.js","ApiExamples-BVxVH4Cj.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-BxdQ2vIi.js","shallow-BjV2tFiD.js","getApiPlaygroundDisplay-C_55tL4O.js","CodeSnippet-C0JpiCOC.js","CodeSnippets-w9Ps7djG.js","Page-DTNSD-0M.js","getPastedJson-BDfB-H8d.js","icon-g-kUkkO9.js","MethodPill-v4l6fq0h.js","DuplicateIcon-CvLo-CfU.js","createIcon-165clrrV.js","DynamicMarkdown-D3RQ-fEj.js","SectionHeading-vvo-3yLf.js","axios-vUo_bRtp.js","Markdown-CMT1uFWQ.js","clsx-C8f2yC9R.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-CI2D8R2Y.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-k78Wrw_e.js"]}