> ## Documentation Index
> Fetch the complete documentation index at: https://surf-dcinside-api.kr.ask.surf/llms.txt
> Use this file to discover all available pages before exploring further.

# Set Weights

> Sets the weights of the publish score. They apply from the next cycle.

<div style={{ maxWidth: 760 }}>
  <h2 style={{ fontSize: "22px", marginBottom: 8 }}>Overview</h2>

  <Warning>
    **Not in MVP scope.** Until this call is available, the weights stay at the first-trial setting: `views = 1` and every other weight `0`.
  </Warning>

  The **Set Weights** API sets how the four model outputs combine into the publish score, `w_v·P(views) + w_c·P(comments) + w_u·P(up) − w_d·downvote_share`. DCinside chooses the weights and the version name. The new weights apply from the next cycle, and every cycle response carries the `weights_version` that produced its scores.

  <Note>
    The first trial sets `views` to `1` and the rest to `0`, so the score equals `p_views`. The example on this page is that setting.
  </Note>

  <Warning>
    If the request fails validation, the previous weights stay in force and nothing changes. `hide` and `deletion` are reserved for later heads and must be `0` or left out. At least one of `views`, `comments` and `up` must be above `0`.
  </Warning>

  <h3 style={{ marginTop: 20 }}>Cadence</h3>

  <CardGroup cols={2}>
    <Card title="When you change them" icon="sliders">
      There is no schedule. Send new weights whenever DCinside wants to change the ranking.
    </Card>

    <Card title="Takes effect next cycle" icon="clock">
      The response names the first cycle the weights apply to. Read the current and previous version with [`GET /v1/weights`](/get-weights).
    </Card>
  </CardGroup>

  ***

  <h2 style={{ fontSize: "22px", marginBottom: 8 }}>Request Attributes</h2>

  <ParamField body="version" type="string" required>
    Chosen by DCinside. Letters, digits, `.`, `_` and `-`, up to 64 characters. Never reused: the same version with the same body is accepted again, and with a different body it returns 409.
  </ParamField>

  <ParamField body="weights" type="object" required>
    Publish-score weights. At least one of `views`, `comments` and `up` must be above 0.

    <Expandable title="properties">
      <ParamField body="views" type="number" required>
        Weight on `p_views`.
      </ParamField>

      <ParamField body="comments" type="number" required>
        Weight on `p_comments`.
      </ParamField>

      <ParamField body="up" type="number" required>
        Weight on `p_up`.
      </ParamField>

      <ParamField body="downvote_share" type="number" required>
        Weight on the predicted down-vote share. It is subtracted, so send it as a positive number.
      </ParamField>

      <ParamField body="hide" type="integer">
        Reserved for the later hide head. Must be 0 or left out.
      </ParamField>

      <ParamField body="deletion" type="integer">
        Reserved for the later deletion head. Must be 0 or left out.
      </ParamField>
    </Expandable>
  </ParamField>

  <ParamField body="note" type="string">
    Optional, up to 500 characters.
  </ParamField>

  ***

  <h2 style={{ fontSize: "22px", marginBottom: 8 }}>Response Attributes</h2>

  <ResponseField name="version" type="string" required>
    The version now in force.
  </ResponseField>

  <ResponseField name="first_cycle_time" type="string" required>
    The first cycle the weights apply to, which is the next one.
  </ResponseField>

  ***
</div>

<RequestExample>
  ```bash cURL theme={null}
  curl --request PUT \
    --url "https://rtb.example.com/v1/weights" \
    --header "Authorization: <api-key>" \
    --header "Content-Type: application/json" \
    --data '{
      "version": "w-1",
      "weights": { "views": 1, "comments": 0, "up": 0, "downvote_share": 0 },
      "note": "first trial: views only"
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.put(
      "https://rtb.example.com/v1/weights",
      headers={"Authorization": "<api-key>"},
      json={
          "version": "w-1",
          "weights": {"views": 1, "comments": 0, "up": 0, "downvote_share": 0},
          "note": "first trial: views only",
      },
  )
  ack = response.json()
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://rtb.example.com/v1/weights", {
    method: "PUT",
    headers: { Authorization: "<api-key>", "Content-Type": "application/json" },
    body: JSON.stringify({
      version: "w-1",
      weights: { views: 1, comments: 0, up: 0, downvote_share: 0 },
      note: "first trial: views only",
    }),
  });
  const ack = await response.json();
  ```
</RequestExample>

<ResponseExample>
  ```json 200 — accepted theme={null}
  {
    "version": "w-1",
    "first_cycle_time": "2026-09-29T02:10:00+09:00"
  }
  ```

  ```json 422 — all three weights are zero theme={null}
  {
    "error": {
      "code": "unprocessable",
      "message": "weights are not acceptable",
      "fields": [
        {
          "path": "weights",
          "problem": "at least one of views, comments and up must be above 0"
        }
      ]
    }
  }
  ```
</ResponseExample>


## OpenAPI

````yaml openapi.json PUT /v1/weights
openapi: 3.0.3
info:
  title: DCinside RTB API
  description: >-
    Publish scores for DCinside's Real-Time Best candidate pool. DCinside makes
    one call per five-minute cycle and reads the scores in the response. Version
    1 is a proposal for the technical exchange with DCinside: calls, field names
    and limits can change until both sides agree.
  version: 1.0.0
servers:
  - url: https://{host}
    description: Issued by Surf together with the API key.
    variables:
      host:
        default: rtb.example.com
        description: >-
          Host name issued by Surf for the environment (rehearsal or
          production). The default is a placeholder.
security:
  - ApiKey: []
tags:
  - name: Scoring
    description: One call per five-minute cycle, and re-reading a stored cycle.
  - name: Images
    description: Post images, uploaded once per post, separately from scoring.
  - name: Outcomes
    description: Not in MVP scope. How placed posts performed. Used for learning.
  - name: Weights
    description: Not in MVP scope. The weights of the publish score.
  - name: Health
    description: Service state.
paths:
  /v1/weights:
    put:
      tags:
        - Weights
      summary: Set Weights
      description: >-
        Not in MVP scope. Sets the weights of the publish score. They apply from
        the next cycle. If the request fails validation the previous weights
        stay in force.
      operationId: putWeights
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WeightsRequest'
            example:
              version: w-1
              weights:
                views: 1
                comments: 0
                up: 0
                downvote_share: 0
              note: 'first trial: views only'
      responses:
        '200':
          description: Accepted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WeightsAck'
              example:
                version: w-1
                first_cycle_time: '2026-09-29T02:10:00+09:00'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Unprocessable'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/ServerError'
components:
  schemas:
    WeightsRequest:
      type: object
      properties:
        version:
          type: string
          pattern: ^[A-Za-z0-9._-]{1,64}$
          example: w-1
          description: >-
            Chosen by DCinside. Letters, digits, `.`, `_` and `-`, up to 64
            characters. Never reused: the same version with the same body is
            accepted again, and with a different body it returns 409.
        weights:
          $ref: '#/components/schemas/WeightSet'
        note:
          type: string
          maxLength: 500
          example: 'first trial: views only'
          description: Optional, up to 500 characters.
      required:
        - version
        - weights
    WeightsAck:
      type: object
      properties:
        version:
          type: string
          example: w-1
          description: The version now in force.
        first_cycle_time:
          type: string
          format: date-time
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:[0-5][05]:00\+09:00$
          description: The first cycle the weights apply to, which is the next one.
          example: '2026-09-29T02:10:00+09:00'
      required:
        - version
        - first_cycle_time
    WeightSet:
      type: object
      properties:
        views:
          type: number
          minimum: 0
          maximum: 10
          example: 1
          description: Weight on `p_views`.
        comments:
          type: number
          minimum: 0
          maximum: 10
          example: 0
          description: Weight on `p_comments`.
        up:
          type: number
          minimum: 0
          maximum: 10
          example: 0
          description: Weight on `p_up`.
        downvote_share:
          type: number
          minimum: 0
          maximum: 10
          example: 0
          description: >-
            Weight on the predicted down-vote share. It is subtracted, so send
            it as a positive number.
        hide:
          type: integer
          enum:
            - 0
          example: 0
          description: Reserved for the later hide head. Must be 0 or left out.
        deletion:
          type: integer
          enum:
            - 0
          example: 0
          description: Reserved for the later deletion head. Must be 0 or left out.
      required:
        - views
        - comments
        - up
        - downvote_share
      description: >-
        Publish-score weights. At least one of `views`, `comments` and `up` must
        be above 0.
    Error:
      type: object
      properties:
        error:
          $ref: '#/components/schemas/ErrorBody'
      required:
        - error
    ErrorBody:
      type: object
      properties:
        code:
          type: string
          example: bad_request
          description: Machine-readable code. See Errors.
        message:
          type: string
          example: 2 fields failed validation
          description: Human-readable summary.
        fields:
          type: array
          items:
            $ref: '#/components/schemas/ErrorField'
          description: Every failing field, when the error is about the body.
      required:
        - code
        - message
    ErrorField:
      type: object
      properties:
        path:
          type: string
          example: candidates[0].created_at
          description: Path of the failing field.
        problem:
          type: string
          example: missing +09:00 offset
          description: What is wrong with it.
      required:
        - path
        - problem
  responses:
    BadRequest:
      description: >-
        The body is not valid JSON, or a field fails the schema. The error lists
        every failing path. Nothing is stored.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: bad_request
              message: 2 fields failed validation
              fields:
                - path: candidates[0].created_at
                  problem: missing +09:00 offset
                - path: engagement[3].views
                  problem: must be a non-negative integer or null
    Unauthorized:
      description: The API key is missing or unknown.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: unauthorized
              message: API key missing or unknown
    Forbidden:
      description: The key has no scope for this call.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: forbidden
              message: this key cannot call PUT /v1/weights
    Conflict:
      description: The id was already used with a different body. The first body stays.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: cycle_conflict
              message: cycle 20260929T0205 was already received with a different body
    Unprocessable:
      description: >-
        The body is valid JSON and matches the schema, but the values are not
        acceptable. Nothing is stored.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: unprocessable
              message: cycle_time is not on the 5-minute grid
              fields:
                - path: cycle_time
                  problem: must be a multiple of 5 minutes
    RateLimited:
      description: >-
        Too many calls. Wait for `Retry-After` seconds, then repeat the same
        call.
      headers:
        Retry-After:
          description: Seconds to wait.
          schema:
            type: integer
            example: 10
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: rate_limited
              message: too many calls, retry in 10 s
    ServerError:
      description: Our failure. No scores. DCinside skips the cycle and our alert fires.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: server_error
              message: internal error
  securitySchemes:
    ApiKey:
      type: apiKey
      name: Authorization
      in: header
      description: >-
        The API key issued for the environment, sent as the whole header value.
        Two keys are valid during a rotation.

````