openapi: "3.1.0"
info:
  title: 短.在线 Agent API
  version: "1.0.0"
  description: >
    短.在线 agent API. Full schema at /openapi.json.
    Session cookie auth is optional. v1 is stable; breaking changes use a new path prefix.
    Caller-supplied source is a client hint only. Errors include RFC 9457 fields plus error/message.
servers:
  - url: https://xn--s7y.xn--3ds443g
  - url: https://短.在线
security:
  - {}
  - sessionCookie: []
paths:
  /v1/links:
    post:
      operationId: createLink
      summary: Create a short link
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            maxLength: 256
        - name: X-Request-Id
          in: header
          required: false
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                url: { type: string, format: uri, maxLength: 2048 }
                longUrl: { type: string, format: uri, maxLength: 2048 }
                alias:
                  type: [string, "null"]
                  pattern: "^[A-Za-z0-9][A-Za-z0-9_-]{0,31}$"
                  maxLength: 32
                source: { type: string, example: agent }
                locale: { type: string, enum: [en, zh-CN] }
              anyOf:
                - required: [url]
                - required: [longUrl]
      responses:
        "201":
          description: Created
        "200":
          description: Idempotent replay
        "202":
          description: Quarantined (LINK_QUARANTINED). Poll GET /v1/links/{id}.
        "400":
          description: INVALID_URL | RESERVED_ALIAS | IDEMPOTENCY_KEY_REQUIRED | VALIDATION_ERROR
        "401":
          description: AUTH_REQUIRED
        "403":
          description: BLOCKED_DESTINATION
        "409":
          description: ALIAS_TAKEN | IDEMPOTENCY_CONFLICT
        "429":
          description: RATE_LIMITED
          headers:
            Retry-After:
              schema: { type: integer }
        "503":
          description: INTERNAL_ERROR
  /v1/links/{id}:
    get:
      operationId: getLinkStatus
      summary: Get link status
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            maxLength: 32
      responses:
        "200":
          description: Current state (destination omitted while quarantined)
        "404":
          description: Unknown short code
components:
  securitySchemes:
    sessionCookie:
      type: apiKey
      in: cookie
      name: duan_session
