About the RTB API
Real-Time Best (RTB) boards on DCinside are filled from a pool of candidate posts. The RTB API is how DCinside hands that pool to Surf and gets a publish score for every pending post back, once per cycle (five minutes by default). Surf builds the features, runs the model and applies the weights DCinside sets. DCinside applies its own hard gate and publishes. Every call is made by DCinside, so DCinside only ever connects outward. Scores come back in the response to the cycle call itself. The trial candidates are the full admin extraction queue that operators review, about 2,200 posts a day. See Rollout Stages for the dress rehearsal and the trial stages.Cadence & freshness
One call per cycle
Every five minutes by default, on the boundaries
:00, :05, :10 and so on, Korean time. That is 288 cycles a day. DCinside’s interval is a setting that starts at 2–5 minutes, and this proposal starts at five.One score per post
A post is scored once, after a 15-minute wait, and the score is repeated unchanged in every later response until the post is removed.
How a cycle works
1
DCinside calls at the cycle boundary
DCinside applies its 24-hour age filter, so posts older than a day are not sent and a pending candidate that crosses 24 hours gets a removal signal. It then makes one
POST /v1/cycles call. The body carries new candidates (text sent once, images uploaded separately), the current engagement of every pending candidate, the admin candidate-score rows and the removals. The cycle id is the idempotency key.2
Surf scores
We add the call to the stored series, build the features and score every candidate whose 15-minute wait is over. Scoring runs inside the request.
3
DCinside reads the response and publishes
The response has one row per pending candidate, with its status and publish score. DCinside passes the scores to its hard gate and publishes.
4
A lost cycle is not lost data
A retry with the same cycle id returns the stored response and never scores twice. If nothing usable arrives in time, DCinside skips that cycle, and
GET /v1/scores/{cycle_id} still returns the stored result.The calls
Who does what
DCinside
DCinside
- Extracts candidates and applies the 24-hour age filter
- Sends each post’s text once and its images once, when it becomes a candidate
- Makes every call, at every cycle boundary
- Runs the hard gate on its publishing side: at most 7 posts of one category and 6 of one gallery in the last 20 on a tier, no more than 2 in a row from a gallery, one post per event, the safety filter and the publishing rate
- Later, not in MVP scope: sets the weights of the publish score and sends outcomes for the posts it placed
Surf
Surf
- Builds the features and runs the model inside each cycle call
- Keeps the engagement series and the outcome store
- Returns the scores, versions and counts with every response
- Watches the service and alerts in Slack if no cycle call arrives for 15 minutes
- Later, not in MVP scope: retrains the model from the outcomes
Ready to get started?
Start with the conventions every call shares, then open Score a Cycle.