openapi: 3.0.3
info:
  title: Jobmore 企業向け API
  version: 1.0.0
  description: |
    Jobmore の企業（Organization）向け公開 API です。求人の管理など、企業アカウントの
    操作をプログラムから自動化できます。AI エージェントによる自動化での利用も想定しています。

    ## 認証

    すべてのエンドポイントは API キー認証を要求します。HTTP ヘッダに以下を付与してください。

    ```
    Authorization: Api-Key <発行された平文キー>
    ```

    API キーは企業ダッシュボードの「Security（セキュリティ）」設定から発行できます。
    キーは発行時に一度だけ表示されるため、安全な場所に保管してください。各キーは特定の
    企業（Organization）に紐付き、その企業のリソースだけを操作できます。

    ## ベース URL

    ```
    https://jobmore.co.jp
    ```

    各エンドポイントのパスは `/api/v1/...` で始まります。

    ## レート制限

    API キー単位で **100 リクエスト / 分** に制限されます。超過すると `429 Too Many
    Requests` が返ります。時間をおいて再試行してください。

    ## エラー形式

    エラー時は次の形の JSON を返します。

    ```json
    {
      "detail": "人間可読のエラー説明",
      "code": "machine_readable_code",
      "errors": { "field_name": ["フィールド単位のエラー"] }
    }
    ```

    `errors` はバリデーションエラー時のみ含まれます。`code` の例: `not_authenticated`,
    `permission_denied`, `not_found`, `validation_error`, `throttled`。

    ## バージョニング

    本 API は `/api/v1/` で提供されます。後方互換性のない変更を行う場合は新バージョンを
    発行し、旧バージョンには十分な告知期間を設けます。
  contact:
    name: Jobmore サポート
    url: https://jobmore.co.jp/
paths:
  /api/v1/employer/jobs/:
    get:
      operationId: employer_jobs_list
      description: |-
        求人一覧取得。

        検索キーワードがある場合はOpenSearch駆動のページネーションを使用し、
        PostgreSQLへの巨大IN句を回避する。
        検索なしの場合は既存のCursorPaginationフロー。
      parameters:
      - name: cursor
        required: false
        in: query
        description: The pagination cursor value.
        schema:
          type: string
      - name: ordering
        required: false
        in: query
        description: Which field to use when ordering the results.
        schema:
          type: string
      - name: page_size
        required: false
        in: query
        description: Number of results to return per page.
        schema:
          type: integer
      - name: search
        required: false
        in: query
        description: A search term.
        schema:
          type: string
      tags:
      - employer
      security:
      - apiKeyAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedEmployerJobListList'
          description: ''
        '401':
          description: 認証に失敗しました（Api-Key が無効または未指定）。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '403':
          description: この操作を行う権限がありません。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '429':
          description: レート制限（100 リクエスト/分/キー）を超過しました。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
    post:
      operationId: employer_jobs_create
      description: |-
        求人作成。

        Args:
            request: リクエストオブジェクト
            args: 可変長引数
            kwargs: キーワード引数

        Returns:
            Response: 作成された求人
      parameters: []
      tags:
      - employer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EmployerJobCreateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/EmployerJobCreateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/EmployerJobCreateRequest'
        required: true
      security:
      - apiKeyAuth: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmployerJobCreate'
          description: ''
        '401':
          description: 認証に失敗しました（Api-Key が無効または未指定）。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '403':
          description: この操作を行う権限がありません。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '429':
          description: レート制限（100 リクエスト/分/キー）を超過しました。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
  /api/v1/employer/jobs/{job_id}/:
    get:
      operationId: employer_jobs_retrieve
      description: |-
        企業向け求人管理API。

        認証:
          - ダッシュボード経由（セッション/JWT）— 既存の UI フロー
          - API キー経由（``Authorization: Api-Key <key>``）— 外部企業の公開API

        API キーでアクセスできるのは求人 CRUD および状態遷移・画像管理のみ。
        ``preview_token`` はログインユーザーに紐付く機能のため、APIキー経由では
        403 を返す。
      parameters:
      - in: path
        name: job_id
        schema:
          type: string
        required: true
      tags:
      - employer
      security:
      - apiKeyAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmployerJobDetail'
          description: ''
        '401':
          description: 認証に失敗しました（Api-Key が無効または未指定）。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '403':
          description: この操作を行う権限がありません。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '429':
          description: レート制限（100 リクエスト/分/キー）を超過しました。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
    put:
      operationId: employer_jobs_update
      description: |-
        求人更新。

        Args:
            request: リクエストオブジェクト
            args: 可変長引数
            kwargs: キーワード引数

        Returns:
            Response: 更新された求人
      parameters:
      - in: path
        name: job_id
        schema:
          type: string
        required: true
      tags:
      - employer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EmployerJobUpdateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/EmployerJobUpdateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/EmployerJobUpdateRequest'
        required: true
      security:
      - apiKeyAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmployerJobUpdate'
          description: ''
        '401':
          description: 認証に失敗しました（Api-Key が無効または未指定）。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '403':
          description: この操作を行う権限がありません。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '429':
          description: レート制限（100 リクエスト/分/キー）を超過しました。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
    delete:
      operationId: employer_jobs_destroy
      description: |-
        企業向け求人管理API。

        認証:
          - ダッシュボード経由（セッション/JWT）— 既存の UI フロー
          - API キー経由（``Authorization: Api-Key <key>``）— 外部企業の公開API

        API キーでアクセスできるのは求人 CRUD および状態遷移・画像管理のみ。
        ``preview_token`` はログインユーザーに紐付く機能のため、APIキー経由では
        403 を返す。
      parameters:
      - in: path
        name: job_id
        schema:
          type: string
        required: true
      tags:
      - employer
      security:
      - apiKeyAuth: []
      responses:
        '204':
          description: No response body
        '401':
          description: 認証に失敗しました（Api-Key が無効または未指定）。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '403':
          description: この操作を行う権限がありません。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '429':
          description: レート制限（100 リクエスト/分/キー）を超過しました。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
    patch:
      operationId: employer_jobs_partial_update
      description: |-
        企業向け求人管理API。

        認証:
          - ダッシュボード経由（セッション/JWT）— 既存の UI フロー
          - API キー経由（``Authorization: Api-Key <key>``）— 外部企業の公開API

        API キーでアクセスできるのは求人 CRUD および状態遷移・画像管理のみ。
        ``preview_token`` はログインユーザーに紐付く機能のため、APIキー経由では
        403 を返す。
      parameters:
      - in: path
        name: job_id
        schema:
          type: string
        required: true
      tags:
      - employer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedEmployerJobUpdateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedEmployerJobUpdateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedEmployerJobUpdateRequest'
      security:
      - apiKeyAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmployerJobUpdate'
          description: ''
        '401':
          description: 認証に失敗しました（Api-Key が無効または未指定）。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '403':
          description: この操作を行う権限がありません。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '429':
          description: レート制限（100 リクエスト/分/キー）を超過しました。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
  /api/v1/employer/jobs/{job_id}/duplicate/:
    post:
      operationId: employer_jobs_duplicate_create
      description: 既存の求人を下書きとして複製し、新しく作成された求人を返す。リクエストボディは不要。
      summary: 求人を複製する
      parameters:
      - in: path
        name: job_id
        schema:
          type: string
        required: true
      tags:
      - employer
      security:
      - apiKeyAuth: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmployerJobDetail'
          description: ''
        '401':
          description: 認証に失敗しました（Api-Key が無効または未指定）。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '403':
          description: この操作を行う権限がありません。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '429':
          description: レート制限（100 リクエスト/分/キー）を超過しました。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
  /api/v1/employer/jobs/{job_id}/expire/:
    post:
      operationId: employer_jobs_expire_create
      description: 求人を掲載終了（expired）にする。リクエストボディは不要。許可されていないステータス遷移の場合は 409 を返す。
      summary: 求人を掲載終了（期限切れ）にする
      parameters:
      - in: path
        name: job_id
        schema:
          type: string
        required: true
      tags:
      - employer
      security:
      - apiKeyAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmployerJobDetail'
          description: ''
        '409':
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    description: 人間可読のエラー説明。
                  code:
                    type: string
                    description: 機械可読のエラーコード。
                  errors:
                    type: object
                    additionalProperties: true
                    description: フィールド単位のバリデーションエラー（該当時のみ）。
                required:
                - detail
                - code
          description: 許可されていないステータス遷移。
        '401':
          description: 認証に失敗しました（Api-Key が無効または未指定）。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '403':
          description: この操作を行う権限がありません。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '429':
          description: レート制限（100 リクエスト/分/キー）を超過しました。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
  /api/v1/employer/jobs/{job_id}/fill/:
    post:
      operationId: employer_jobs_fill_create
      description: 求人を募集終了（filled）にする。リクエストボディは不要。許可されていないステータス遷移の場合は 409 を返す。
      summary: 求人を募集終了にする
      parameters:
      - in: path
        name: job_id
        schema:
          type: string
        required: true
      tags:
      - employer
      security:
      - apiKeyAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmployerJobDetail'
          description: ''
        '409':
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    description: 人間可読のエラー説明。
                  code:
                    type: string
                    description: 機械可読のエラーコード。
                  errors:
                    type: object
                    additionalProperties: true
                    description: フィールド単位のバリデーションエラー（該当時のみ）。
                required:
                - detail
                - code
          description: 許可されていないステータス遷移。
        '401':
          description: 認証に失敗しました（Api-Key が無効または未指定）。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '403':
          description: この操作を行う権限がありません。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '429':
          description: レート制限（100 リクエスト/分/キー）を超過しました。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
  /api/v1/employer/jobs/{job_id}/images/:
    get:
      operationId: employer_jobs_images_retrieve
      description: 求人に紐づくダウンロード済みの画像一覧を返す。
      summary: 求人画像の一覧を取得する
      parameters:
      - in: path
        name: job_id
        schema:
          type: string
        required: true
      tags:
      - employer
      security:
      - apiKeyAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/EmployerJobImage'
          description: ダウンロード済みの画像一覧。
        '401':
          description: 認証に失敗しました（Api-Key が無効または未指定）。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '403':
          description: この操作を行う権限がありません。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '429':
          description: レート制限（100 リクエスト/分/キー）を超過しました。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
    post:
      operationId: employer_jobs_images_create
      description: 求人に画像を 1 枚追加する。1 求人あたり最大 10 枚、アスペクト比は 4:3 近傍、5MB 以下の JPEG / PNG
        / WebP に限る。
      summary: 求人画像をアップロードする
      parameters:
      - in: path
        name: job_id
        schema:
          type: string
        required: true
      tags:
      - employer
      requestBody:
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/JobImageUploadRequest'
        required: true
      security:
      - apiKeyAuth: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmployerJobImage'
          description: ''
        '400':
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    description: 人間可読のエラー説明。
                  code:
                    type: string
                    description: 機械可読のエラーコード。
                  errors:
                    type: object
                    additionalProperties: true
                    description: フィールド単位のバリデーションエラー（該当時のみ）。
                required:
                - detail
                - code
          description: 画像が不正（形式/サイズ/アスペクト比）、または上限 10 枚を超過。
        '401':
          description: 認証に失敗しました（Api-Key が無効または未指定）。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '403':
          description: この操作を行う権限がありません。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '429':
          description: レート制限（100 リクエスト/分/キー）を超過しました。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
  /api/v1/employer/jobs/{job_id}/images/{image_id}/:
    delete:
      operationId: employer_jobs_images_destroy
      description: 指定した画像を削除する。リクエストボディは不要。
      summary: 求人画像を削除する
      parameters:
      - in: path
        name: image_id
        schema:
          type: string
          pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$
        required: true
      - in: path
        name: job_id
        schema:
          type: string
        required: true
      tags:
      - employer
      security:
      - apiKeyAuth: []
      responses:
        '204':
          description: 削除に成功（本文なし）。
        '404':
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    description: 人間可読のエラー説明。
                  code:
                    type: string
                    description: 機械可読のエラーコード。
                  errors:
                    type: object
                    additionalProperties: true
                    description: フィールド単位のバリデーションエラー（該当時のみ）。
                required:
                - detail
                - code
          description: 指定した画像が見つからない。
        '401':
          description: 認証に失敗しました（Api-Key が無効または未指定）。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '403':
          description: この操作を行う権限がありません。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '429':
          description: レート制限（100 リクエスト/分/キー）を超過しました。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
    patch:
      operationId: employer_jobs_images_partial_update
      description: 画像の ``is_main`` / ``alt_text`` / ``display_order`` を更新する。
      summary: 求人画像のメタデータを更新する
      parameters:
      - in: path
        name: image_id
        schema:
          type: string
          pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$
        required: true
      - in: path
        name: job_id
        schema:
          type: string
        required: true
      tags:
      - employer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedJobImageUpdateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedJobImageUpdateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedJobImageUpdateRequest'
      security:
      - apiKeyAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmployerJobImage'
          description: ''
        '404':
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    description: 人間可読のエラー説明。
                  code:
                    type: string
                    description: 機械可読のエラーコード。
                  errors:
                    type: object
                    additionalProperties: true
                    description: フィールド単位のバリデーションエラー（該当時のみ）。
                required:
                - detail
                - code
          description: 指定した画像が見つからない。
        '401':
          description: 認証に失敗しました（Api-Key が無効または未指定）。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '403':
          description: この操作を行う権限がありません。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '429':
          description: レート制限（100 リクエスト/分/キー）を超過しました。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
  /api/v1/employer/jobs/{job_id}/publish/:
    post:
      operationId: employer_jobs_publish_create
      description: 指定した求人を公開状態にする。リクエストボディは不要。必須項目の不足などで公開できない場合は 400 を返す。
      summary: 求人を公開する
      parameters:
      - in: path
        name: job_id
        schema:
          type: string
        required: true
      tags:
      - employer
      security:
      - apiKeyAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmployerJobDetail'
          description: ''
        '400':
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    description: 人間可読のエラー説明。
                  code:
                    type: string
                    description: 機械可読のエラーコード。
                  errors:
                    type: object
                    additionalProperties: true
                    description: フィールド単位のバリデーションエラー（該当時のみ）。
                required:
                - detail
                - code
          description: 公開できなかった（必須項目の不足など）。
        '401':
          description: 認証に失敗しました（Api-Key が無効または未指定）。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '403':
          description: この操作を行う権限がありません。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '429':
          description: レート制限（100 リクエスト/分/キー）を超過しました。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
  /api/v1/employer/jobs/{job_id}/unpublish/:
    post:
      operationId: employer_jobs_unpublish_create
      description: 公開中の求人を下書きに戻す。リクエストボディは不要。許可されていないステータス遷移の場合は 409 を返す。
      summary: 求人を非公開（下書き）に戻す
      parameters:
      - in: path
        name: job_id
        schema:
          type: string
        required: true
      tags:
      - employer
      security:
      - apiKeyAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmployerJobDetail'
          description: ''
        '409':
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    description: 人間可読のエラー説明。
                  code:
                    type: string
                    description: 機械可読のエラーコード。
                  errors:
                    type: object
                    additionalProperties: true
                    description: フィールド単位のバリデーションエラー（該当時のみ）。
                required:
                - detail
                - code
          description: 許可されていないステータス遷移。
        '401':
          description: 認証に失敗しました（Api-Key が無効または未指定）。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '403':
          description: この操作を行う権限がありません。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '429':
          description: レート制限（100 リクエスト/分/キー）を超過しました。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
  /api/v1/employer/jobs/bulk_delete/:
    post:
      operationId: employer_jobs_bulk_delete_create
      description: '``job_ids`` の配列を受け取り、自社の該当求人をまとめて削除する（一度に最大 100 件）。'
      summary: 求人を一括削除する
      parameters: []
      tags:
      - employer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EmployerJobBulkDeleteRequest'
        required: true
      security:
      - apiKeyAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmployerJobBulkDeleteResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    description: 人間可読のエラー説明。
                  code:
                    type: string
                    description: 機械可読のエラーコード。
                  errors:
                    type: object
                    additionalProperties: true
                    description: フィールド単位のバリデーションエラー（該当時のみ）。
                required:
                - detail
                - code
          description: '``job_ids`` が不正（未指定 / 空 / 文字列の配列でない / 100 件超過）。``errors.job_ids``
            に詳細。'
        '401':
          description: 認証に失敗しました（Api-Key が無効または未指定）。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '403':
          description: この操作を行う権限がありません。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '429':
          description: レート制限（100 リクエスト/分/キー）を超過しました。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
  /api/v1/employer/jobs/bulk_update_status/:
    post:
      operationId: employer_jobs_bulk_update_status_create
      description: '``job_ids`` の配列と変更先 ``status`` を受け取り、自社の該当求人をまとめて変更する（一度に最大 100
        件）。``published`` への一括変更時は、AI 生成が未完了の求人が審査待ち（awaiting_review）になったり、必須項目が不足する求人がスキップされたりするため、レスポンスに
        ``awaiting_review_count`` / ``validation_failed_count`` / ``validation_errors``
        が含まれ得る。'
      summary: 求人のステータスを一括変更する
      parameters: []
      tags:
      - employer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EmployerJobBulkUpdateStatusRequest'
        required: true
      security:
      - apiKeyAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmployerJobBulkUpdateStatusResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    description: 人間可読のエラー説明。
                  code:
                    type: string
                    description: 機械可読のエラーコード。
                  errors:
                    type: object
                    additionalProperties: true
                    description: フィールド単位のバリデーションエラー（該当時のみ）。
                required:
                - detail
                - code
          description: '``job_ids`` / ``status`` が不正（未指定 / 空 / 型不正 / 不正な status /
            100 件超過）。``errors`` にフィールド単位の詳細。'
        '409':
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    description: 人間可読のエラー説明。
                  code:
                    type: string
                    description: 機械可読のエラーコード。
                  errors:
                    type: object
                    additionalProperties: true
                    description: フィールド単位のバリデーションエラー（該当時のみ）。
                required:
                - detail
                - code
          description: 許可されていないステータス遷移の求人を含む。
        '401':
          description: 認証に失敗しました（Api-Key が無効または未指定）。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '403':
          description: この操作を行う権限がありません。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '429':
          description: レート制限（100 リクエスト/分/キー）を超過しました。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
components:
  schemas:
    AiGenerationStatusEnum:
      enum:
      - not_ready
      - pending
      - processing
      - completed
      - failed
      - skipped
      type: string
      description: |-
        * `not_ready` - データ未準備
        * `pending` - 未生成
        * `processing` - 生成中
        * `completed` - 完了
        * `failed` - 失敗
        * `skipped` - スキップ
    ApplicationFormLevelEnum:
      enum:
      - minimal
      - basic
      - full
      type: string
      description: |-
        * `minimal` - 簡易（氏名・メールのみ）
        * `basic` - 標準（氏名・メール・電話・生年月日）
        * `full` - 詳細（氏名・メール・電話・生年月日・履歴書）
    BodyFormatEnum:
      enum:
      - plain
      - markdown
      type: string
      description: |-
        * `plain` - Plain
        * `markdown` - Markdown
    CategoryEnum:
      enum:
      - EMPLOYMENT_TYPE
      - WORK_SHIFT
      - SALARY_BENEFITS
      - REQUIREMENTS
      - TARGET_APPLICANTS
      - INDUSTRY_OCCUPATION
      - WORKPLACE_ENVIRONMENT
      - APPLICATION_HIRING
      - OTHER
      type: string
      description: |-
        * `EMPLOYMENT_TYPE` - 雇用形態
        * `WORK_SHIFT` - 勤務体制・シフト
        * `SALARY_BENEFITS` - 給与・待遇
        * `REQUIREMENTS` - 応募条件・経験・スキル
        * `TARGET_APPLICANTS` - 歓迎する人材
        * `INDUSTRY_OCCUPATION` - 業種・職種
        * `WORKPLACE_ENVIRONMENT` - 職場環境
        * `APPLICATION_HIRING` - 応募・採用
        * `OTHER` - その他
    CompanyDescriptionDisplayFormatEnum:
      enum:
      - plain
      - markdown
      type: string
      description: |-
        * `plain` - plain
        * `markdown` - markdown
    EmployerJobBulkDeleteRequest:
      type: object
      description: |-
        求人を一括削除するリクエスト。

        削除対象の求人 ID（``job_id``）の配列を 1〜100 件指定する。
      properties:
        job_ids:
          type: array
          items:
            type: string
            format: uuid
          description: 対象の求人ID（``job_id``・UUID）の配列。1〜100 件。
          maxItems: 100
      required:
      - job_ids
    EmployerJobBulkDeleteResponse:
      type: object
      description: 求人を一括削除した結果。
      properties:
        deleted_count:
          type: integer
          description: 実際に削除された求人数。
        message:
          type: string
          description: 処理結果の人間可読メッセージ。
      required:
      - deleted_count
      - message
    EmployerJobBulkUpdateStatusRequest:
      type: object
      description: |-
        求人ステータスを一括変更するリクエスト。

        対象の求人 ID（``job_id``）の配列（1〜100 件）と変更先 ``status`` を指定する。
      properties:
        job_ids:
          type: array
          items:
            type: string
            format: uuid
          description: 対象の求人ID（``job_id``・UUID）の配列。1〜100 件。
          maxItems: 100
        status:
          allOf:
          - $ref: '#/components/schemas/EmployerJobBulkUpdateStatusStatusEnum'
          description: |-
            変更先のステータス。``published`` / ``draft`` / ``expired`` / ``filled`` のいずれか。

            * `published` - published
            * `draft` - draft
            * `expired` - expired
            * `filled` - filled
      required:
      - job_ids
      - status
    EmployerJobBulkUpdateStatusResponse:
      type: object
      description: |-
        求人ステータス一括変更のレスポンス（200）。

        ``published`` 化時のみ、AI 生成未完了求人の審査待ち化や必須項目不足による
        スキップが起こり得るため、``awaiting_review_count`` /
        ``validation_failed_count`` / ``validation_errors`` が条件付きで含まれる。
      properties:
        updated_count:
          type: integer
          description: 要求したステータスへ実際に変更された求人数。
        message:
          type: string
          description: 処理結果の人間可読メッセージ。
        awaiting_review_count:
          type: integer
          description: '``published`` 化時、AI 生成が未完了のため審査待ち（awaiting_review）に変更された求人数。'
        validation_failed_count:
          type: integer
          description: '``published`` 化時、必須項目不足のため公開をスキップした求人数。'
        validation_errors:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
          description: '``published`` 化時、求人ID（``job_id``）ごとの必須項目エラーメッセージ配列。'
      required:
      - message
      - updated_count
    EmployerJobBulkUpdateStatusStatusEnum:
      enum:
      - published
      - draft
      - expired
      - filled
      type: string
      description: |-
        * `published` - published
        * `draft` - draft
        * `expired` - expired
        * `filled` - filled
    EmployerJobCreate:
      type: object
      description: 求人作成用シリアライザー。
      properties:
        title:
          type: string
          maxLength: 255
        employment_type:
          nullable: true
          title: 雇用形態
          description: |-
            求人の雇用形態。正社員、アルバイト等。

            * `1` - 正社員
            * `2` - アルバイト・パート
            * `3` - 契約社員
            * `4` - 派遣社員
            * `5` - 臨時・期間従業員
            * `6` - 業務委託
            * `7` - インターンシップ
          minimum: -32768
          maximum: 32767
          oneOf:
          - $ref: '#/components/schemas/EmploymentTypeA7aEnum'
          - $ref: '#/components/schemas/NullEnum'
        location_prefecture:
          type: string
          title: 都道府県
          description: 勤務地の都道府県名
          maxLength: 50
        location_city:
          type: string
          title: 市区町村
          description: 勤務地の市区町村名
          maxLength: 100
        location:
          type: string
          title: 勤務地
          description: 勤務地の詳細情報
          maxLength: 500
        access:
          type: string
          title: 交通アクセス
          description: 最寄り駅からの徒歩分数、バス、車などの詳細アクセス情報
        salary_type:
          allOf:
          - $ref: '#/components/schemas/SalaryTypeEnum'
          title: 給与形態
        salary_annual_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 年収（最小）
          description: 円単位
        salary_annual_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 年収（最大）
          description: 円単位
        salary_monthly_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 月給（最小）
          description: 円単位
        salary_monthly_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 月給（最大）
          description: 円単位
        salary_hourly_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 時給（最小）
          description: 円単位
        salary_hourly_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 時給（最大）
          description: 円単位
        salary_daily_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 日給（最小）
          description: 円単位
        salary_daily_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 日給（最大）
          description: 円単位
        description:
          type: string
        working_hours:
          type: string
          title: 勤務時間
        holidays:
          type: string
          title: 休日・休暇
        employment_period:
          type: string
          title: 雇用期間
          maxLength: 500
        body_format:
          allOf:
          - $ref: '#/components/schemas/BodyFormatEnum'
          default: markdown
          description: |-
            本文 (description / qualifications 等) のフォーマット。新規入稿は markdown が既定。

            * `plain` - Plain
            * `markdown` - Markdown
        status:
          $ref: '#/components/schemas/Status5b9Enum'
        qualifications:
          type: string
        hiring_count:
          type: integer
          nullable: true
        benefits_text:
          type: string
        selection_process:
          type: string
        bonus:
          type: string
        allowances:
          type: string
        application_form_level:
          allOf:
          - $ref: '#/components/schemas/ApplicationFormLevelEnum'
          default: minimal
      required:
      - title
    EmployerJobCreateRequest:
      type: object
      description: 求人作成用シリアライザー。
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 255
        employment_type:
          nullable: true
          title: 雇用形態
          description: |-
            求人の雇用形態。正社員、アルバイト等。

            * `1` - 正社員
            * `2` - アルバイト・パート
            * `3` - 契約社員
            * `4` - 派遣社員
            * `5` - 臨時・期間従業員
            * `6` - 業務委託
            * `7` - インターンシップ
          minimum: -32768
          maximum: 32767
          oneOf:
          - $ref: '#/components/schemas/EmploymentTypeA7aEnum'
          - $ref: '#/components/schemas/NullEnum'
        location_prefecture:
          type: string
          title: 都道府県
          description: 勤務地の都道府県名
          maxLength: 50
        location_city:
          type: string
          title: 市区町村
          description: 勤務地の市区町村名
          maxLength: 100
        location:
          type: string
          title: 勤務地
          description: 勤務地の詳細情報
          maxLength: 500
        access:
          type: string
          title: 交通アクセス
          description: 最寄り駅からの徒歩分数、バス、車などの詳細アクセス情報
        salary_type:
          allOf:
          - $ref: '#/components/schemas/SalaryTypeEnum'
          title: 給与形態
        salary_annual_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 年収（最小）
          description: 円単位
        salary_annual_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 年収（最大）
          description: 円単位
        salary_monthly_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 月給（最小）
          description: 円単位
        salary_monthly_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 月給（最大）
          description: 円単位
        salary_hourly_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 時給（最小）
          description: 円単位
        salary_hourly_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 時給（最大）
          description: 円単位
        salary_daily_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 日給（最小）
          description: 円単位
        salary_daily_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 日給（最大）
          description: 円単位
        description:
          type: string
        working_hours:
          type: string
          title: 勤務時間
        holidays:
          type: string
          title: 休日・休暇
        employment_period:
          type: string
          title: 雇用期間
          maxLength: 500
        body_format:
          allOf:
          - $ref: '#/components/schemas/BodyFormatEnum'
          default: markdown
          description: |-
            本文 (description / qualifications 等) のフォーマット。新規入稿は markdown が既定。

            * `plain` - Plain
            * `markdown` - Markdown
        status:
          $ref: '#/components/schemas/Status5b9Enum'
        work_style_attribute_keys:
          type: array
          items:
            type: string
            minLength: 1
          writeOnly: true
        benefit_attribute_keys:
          type: array
          items:
            type: string
            minLength: 1
          writeOnly: true
        qualifications:
          type: string
        hiring_count:
          type: integer
          nullable: true
        benefits_text:
          type: string
        selection_process:
          type: string
        bonus:
          type: string
        allowances:
          type: string
        application_form_level:
          allOf:
          - $ref: '#/components/schemas/ApplicationFormLevelEnum'
          default: minimal
      required:
      - title
    EmployerJobDetail:
      type: object
      description: 求人詳細用シリアライザー。
      properties:
        id:
          type: integer
          readOnly: true
        job_id:
          type: string
          format: uuid
        employment_type:
          nullable: true
          title: 雇用形態
          description: |-
            求人の雇用形態。正社員、アルバイト等。

            * `1` - 正社員
            * `2` - アルバイト・パート
            * `3` - 契約社員
            * `4` - 派遣社員
            * `5` - 臨時・期間従業員
            * `6` - 業務委託
            * `7` - インターンシップ
          minimum: -32768
          maximum: 32767
          oneOf:
          - $ref: '#/components/schemas/EmploymentTypeA7aEnum'
          - $ref: '#/components/schemas/NullEnum'
        employment_type_display:
          type: string
          readOnly: true
        company_name:
          type: string
          readOnly: true
        company_name_display:
          type: string
          readOnly: true
        company_description_display:
          type: string
          readOnly: true
        company_description_display_format:
          allOf:
          - $ref: '#/components/schemas/CompanyDescriptionDisplayFormatEnum'
          readOnly: true
          description: |-
            ``company_description_display`` の本文フォーマット。``"markdown"`` のときフロントは Markdown レンダラを通す（type/wtype 等の提携フィードは ``## 主要取引先`` 等の見出しを含む）。``"plain"`` のときは改行保持の plain 表示で十分。プロパティ実装上、未解決時は ``"plain"`` を返すため空文字は来ない。

            * `plain` - plain
            * `markdown` - markdown
        company_website_url_display:
          type: string
          readOnly: true
        company_address_display:
          type: string
          readOnly: true
        company_postal_code_display:
          type: string
          readOnly: true
        company_prefecture_display:
          type: string
          readOnly: true
        company_city_display:
          type: string
          readOnly: true
        company_phone_number_display:
          type: string
          readOnly: true
        company_founded_year_display:
          type: integer
          readOnly: true
          nullable: true
        company_establishment_date_display:
          type: string
          format: date
          readOnly: true
          nullable: true
        company_establishment_date_precision_display:
          type: string
          readOnly: true
          description: 掲載元の設立日の精度。'day' は年月日、'month' は年月のみ（日は便宜的に1）、'year' は年のみ（月日は便宜的に1）、空文字は精度不明で従来どおり日まで描画してよい。
        company_capital_stock_yen_display:
          type: integer
          format: int64
          nullable: true
          readOnly: true
          description: 掲載元の資本金（円単位）。フロントは 1万円単位で表示する場合 ÷10000 する。
        company_annual_revenue_display:
          type: string
          readOnly: true
          description: 掲載元の売上高（自由記述）。type/wtype 等の提携フィードでは決算期注釈付きで届くため原文をそのまま表示する。
        company_employee_number_display:
          type: integer
          readOnly: true
          nullable: true
        company_size_label_display:
          type: string
          readOnly: true
        company_representative_name_display:
          type: string
          readOnly: true
        company_industry_display:
          type: string
          readOnly: true
        title:
          type: string
          readOnly: true
        description:
          type: string
          readOnly: true
        body_format:
          allOf:
          - $ref: '#/components/schemas/BodyFormatEnum'
          title: 本文フォーマット
          description: |-
            description / working_hours / qualifications 等の本文系フィールドの記法。既存データは plain、新規入稿および XmlFeed クローラ取込みは markdown。

            * `plain` - Plain
            * `markdown` - Markdown
        location_prefecture:
          type: string
          title: 都道府県
          description: 勤務地の都道府県名
          maxLength: 50
        location_city:
          type: string
          title: 市区町村
          description: 勤務地の市区町村名
          maxLength: 100
        location:
          type: string
          title: 勤務地
          description: 勤務地の詳細情報
          maxLength: 500
        access:
          type: string
          title: 交通アクセス
          description: 最寄り駅からの徒歩分数、バス、車などの詳細アクセス情報
        location_display:
          type: string
          readOnly: true
        salary_type:
          allOf:
          - $ref: '#/components/schemas/SalaryTypeEnum'
          title: 給与形態
        salary_annual_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 年収（最小）
          description: 円単位
        salary_annual_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 年収（最大）
          description: 円単位
        salary_monthly_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 月給（最小）
          description: 円単位
        salary_monthly_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 月給（最大）
          description: 円単位
        salary_hourly_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 時給（最小）
          description: 円単位
        salary_hourly_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 時給（最大）
          description: 円単位
        salary_daily_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 日給（最小）
          description: 円単位
        salary_daily_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 日給（最大）
          description: 円単位
        salary_display:
          type: string
          readOnly: true
        working_hours:
          type: string
          title: 勤務時間
        holidays:
          type: string
          title: 休日・休暇
        employment_period:
          type: string
          title: 雇用期間
          maxLength: 500
        status:
          $ref: '#/components/schemas/Status5b9Enum'
        system_published_at:
          type: string
          format: date-time
          nullable: true
          title: システム公開日時
        applications_count:
          type: integer
          readOnly: true
        work_style_attribute_keys:
          type: array
          items:
            type: string
          readOnly: true
        benefit_attribute_keys:
          type: array
          items:
            type: string
          readOnly: true
        source_acquisition_method:
          $ref: '#/components/schemas/SourceAcquisitionMethodEnum'
        source_web_site_name:
          type: string
          maxLength: 100
        source_display_name:
          type: string
          readOnly: true
        effective_published_at:
          type: string
          format: date-time
          nullable: true
          readOnly: true
        effective_expires_at:
          type: string
          format: date-time
          nullable: true
          readOnly: true
        ai_generation_status:
          allOf:
          - $ref: '#/components/schemas/AiGenerationStatusEnum'
          title: AI生成ステータス
          description: |-
            AI生成処理の状態

            * `not_ready` - データ未準備
            * `pending` - 未生成
            * `processing` - 生成中
            * `completed` - 完了
            * `failed` - 失敗
            * `skipped` - スキップ
        images:
          type: array
          items:
            $ref: '#/components/schemas/EmployerJobImage'
          readOnly: true
        job_attributes:
          type: array
          items:
            $ref: '#/components/schemas/JobPostingAttributeMapping'
          readOnly: true
        qualifications:
          type: string
          readOnly: true
        hiring_count:
          type: integer
          nullable: true
          readOnly: true
        benefits_text:
          type: string
          readOnly: true
        selection_process:
          type: string
          readOnly: true
        bonus:
          type: string
          readOnly: true
        allowances:
          type: string
          readOnly: true
        application_form_level:
          type: string
          readOnly: true
        tracking_url:
          type: string
          format: uri
          nullable: true
          readOnly: true
        campaign_is_active:
          type: boolean
          nullable: true
          readOnly: true
        campaign_public_id:
          type: string
          nullable: true
          readOnly: true
      required:
      - allowances
      - application_form_level
      - applications_count
      - benefit_attribute_keys
      - benefits_text
      - bonus
      - campaign_is_active
      - campaign_public_id
      - company_address_display
      - company_annual_revenue_display
      - company_capital_stock_yen_display
      - company_city_display
      - company_description_display
      - company_description_display_format
      - company_employee_number_display
      - company_establishment_date_display
      - company_establishment_date_precision_display
      - company_founded_year_display
      - company_industry_display
      - company_name
      - company_name_display
      - company_phone_number_display
      - company_postal_code_display
      - company_prefecture_display
      - company_representative_name_display
      - company_size_label_display
      - company_website_url_display
      - description
      - effective_expires_at
      - effective_published_at
      - employment_type_display
      - hiring_count
      - id
      - images
      - job_attributes
      - location_display
      - qualifications
      - salary_display
      - selection_process
      - source_display_name
      - title
      - tracking_url
      - work_style_attribute_keys
    EmployerJobImage:
      type: object
      description: |-
        求人画像シリアライザー（employer ダッシュボード用・読み取り用）。

        ``core/apps/api/serializers.py`` の ``JobImageSerializer`` と名前衝突して
        OpenAPI 型が deduplicate されないように明示的にプレフィックス付きにしている
        （ADR-015 で uuid フィールドを employer 側だけ露出するため）。
      properties:
        id:
          type: integer
          readOnly: true
        uuid:
          type: string
          format: uuid
          readOnly: true
          description: API URL 識別子として使う uuid4。PK漏洩・規模推定を防ぐ。
        original_image:
          type: string
          format: uri
          nullable: true
          readOnly: true
        is_main:
          type: boolean
          title: メイン画像
        alt_text:
          type: string
          title: 代替テキスト
          maxLength: 255
        display_order:
          type: integer
          maximum: 2147483647
          minimum: 0
          title: 表示順
      required:
      - id
      - original_image
      - uuid
    EmployerJobList:
      type: object
      description: 求人一覧用シリアライザー（軽量版）。
      properties:
        id:
          type: integer
          readOnly: true
        job_id:
          type: string
          format: uuid
        employment_type:
          nullable: true
          title: 雇用形態
          description: |-
            求人の雇用形態。正社員、アルバイト等。

            * `1` - 正社員
            * `2` - アルバイト・パート
            * `3` - 契約社員
            * `4` - 派遣社員
            * `5` - 臨時・期間従業員
            * `6` - 業務委託
            * `7` - インターンシップ
          minimum: -32768
          maximum: 32767
          oneOf:
          - $ref: '#/components/schemas/EmploymentTypeA7aEnum'
          - $ref: '#/components/schemas/NullEnum'
        employment_type_display:
          type: string
          readOnly: true
        company_name:
          type: string
          readOnly: true
        company_name_display:
          type: string
          readOnly: true
        title:
          type: string
          readOnly: true
        location_city:
          type: string
          title: 市区町村
          description: 勤務地の市区町村名
          maxLength: 100
        location_prefecture:
          type: string
          title: 都道府県
          description: 勤務地の都道府県名
          maxLength: 50
        location_display:
          type: string
          readOnly: true
        salary_display:
          type: string
          readOnly: true
        status:
          $ref: '#/components/schemas/Status5b9Enum'
        system_published_at:
          type: string
          format: date-time
          nullable: true
          title: システム公開日時
        applications_count:
          type: integer
          readOnly: true
        source_acquisition_method:
          $ref: '#/components/schemas/SourceAcquisitionMethodEnum'
        ai_generation_status:
          allOf:
          - $ref: '#/components/schemas/AiGenerationStatusEnum'
          title: AI生成ステータス
          description: |-
            AI生成処理の状態

            * `not_ready` - データ未準備
            * `pending` - 未生成
            * `processing` - 生成中
            * `completed` - 完了
            * `failed` - 失敗
            * `skipped` - スキップ
        images:
          type: array
          items:
            $ref: '#/components/schemas/EmployerJobImage'
          readOnly: true
        campaign_id:
          type: integer
          readOnly: true
          nullable: true
        campaign_is_active:
          type: boolean
          readOnly: true
          nullable: true
        campaign_public_id:
          type: string
          readOnly: true
          nullable: true
        campaign_name:
          type: string
          readOnly: true
          nullable: true
        campaign_plan_label:
          type: string
          nullable: true
          readOnly: true
      required:
      - applications_count
      - campaign_id
      - campaign_is_active
      - campaign_name
      - campaign_plan_label
      - campaign_public_id
      - company_name
      - company_name_display
      - employment_type_display
      - id
      - images
      - location_display
      - salary_display
      - title
    EmployerJobUpdate:
      type: object
      description: 求人更新用シリアライザー。
      properties:
        title:
          type: string
          maxLength: 255
        employment_type:
          nullable: true
          title: 雇用形態
          description: |-
            求人の雇用形態。正社員、アルバイト等。

            * `1` - 正社員
            * `2` - アルバイト・パート
            * `3` - 契約社員
            * `4` - 派遣社員
            * `5` - 臨時・期間従業員
            * `6` - 業務委託
            * `7` - インターンシップ
          minimum: -32768
          maximum: 32767
          oneOf:
          - $ref: '#/components/schemas/EmploymentTypeA7aEnum'
          - $ref: '#/components/schemas/NullEnum'
        location_prefecture:
          type: string
          title: 都道府県
          description: 勤務地の都道府県名
          maxLength: 50
        location_city:
          type: string
          title: 市区町村
          description: 勤務地の市区町村名
          maxLength: 100
        location:
          type: string
          title: 勤務地
          description: 勤務地の詳細情報
          maxLength: 500
        access:
          type: string
          title: 交通アクセス
          description: 最寄り駅からの徒歩分数、バス、車などの詳細アクセス情報
        salary_type:
          allOf:
          - $ref: '#/components/schemas/SalaryTypeEnum'
          title: 給与形態
        salary_annual_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 年収（最小）
          description: 円単位
        salary_annual_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 年収（最大）
          description: 円単位
        salary_monthly_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 月給（最小）
          description: 円単位
        salary_monthly_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 月給（最大）
          description: 円単位
        salary_hourly_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 時給（最小）
          description: 円単位
        salary_hourly_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 時給（最大）
          description: 円単位
        salary_daily_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 日給（最小）
          description: 円単位
        salary_daily_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 日給（最大）
          description: 円単位
        description:
          type: string
        working_hours:
          type: string
          title: 勤務時間
        holidays:
          type: string
          title: 休日・休暇
        employment_period:
          type: string
          title: 雇用期間
          maxLength: 500
        body_format:
          allOf:
          - $ref: '#/components/schemas/BodyFormatEnum'
          description: |-
            本文 (description / qualifications 等) のフォーマット。

            * `plain` - Plain
            * `markdown` - Markdown
        qualifications:
          type: string
        hiring_count:
          type: integer
          nullable: true
        benefits_text:
          type: string
        selection_process:
          type: string
        bonus:
          type: string
        allowances:
          type: string
        application_form_level:
          $ref: '#/components/schemas/ApplicationFormLevelEnum'
      required:
      - title
    EmployerJobUpdateRequest:
      type: object
      description: 求人更新用シリアライザー。
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 255
        employment_type:
          nullable: true
          title: 雇用形態
          description: |-
            求人の雇用形態。正社員、アルバイト等。

            * `1` - 正社員
            * `2` - アルバイト・パート
            * `3` - 契約社員
            * `4` - 派遣社員
            * `5` - 臨時・期間従業員
            * `6` - 業務委託
            * `7` - インターンシップ
          minimum: -32768
          maximum: 32767
          oneOf:
          - $ref: '#/components/schemas/EmploymentTypeA7aEnum'
          - $ref: '#/components/schemas/NullEnum'
        location_prefecture:
          type: string
          title: 都道府県
          description: 勤務地の都道府県名
          maxLength: 50
        location_city:
          type: string
          title: 市区町村
          description: 勤務地の市区町村名
          maxLength: 100
        location:
          type: string
          title: 勤務地
          description: 勤務地の詳細情報
          maxLength: 500
        access:
          type: string
          title: 交通アクセス
          description: 最寄り駅からの徒歩分数、バス、車などの詳細アクセス情報
        salary_type:
          allOf:
          - $ref: '#/components/schemas/SalaryTypeEnum'
          title: 給与形態
        salary_annual_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 年収（最小）
          description: 円単位
        salary_annual_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 年収（最大）
          description: 円単位
        salary_monthly_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 月給（最小）
          description: 円単位
        salary_monthly_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 月給（最大）
          description: 円単位
        salary_hourly_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 時給（最小）
          description: 円単位
        salary_hourly_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 時給（最大）
          description: 円単位
        salary_daily_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 日給（最小）
          description: 円単位
        salary_daily_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 日給（最大）
          description: 円単位
        description:
          type: string
        working_hours:
          type: string
          title: 勤務時間
        holidays:
          type: string
          title: 休日・休暇
        employment_period:
          type: string
          title: 雇用期間
          maxLength: 500
        body_format:
          allOf:
          - $ref: '#/components/schemas/BodyFormatEnum'
          description: |-
            本文 (description / qualifications 等) のフォーマット。

            * `plain` - Plain
            * `markdown` - Markdown
        work_style_attribute_keys:
          type: array
          items:
            type: string
            minLength: 1
          writeOnly: true
        benefit_attribute_keys:
          type: array
          items:
            type: string
            minLength: 1
          writeOnly: true
        qualifications:
          type: string
        hiring_count:
          type: integer
          nullable: true
        benefits_text:
          type: string
        selection_process:
          type: string
        bonus:
          type: string
        allowances:
          type: string
        application_form_level:
          $ref: '#/components/schemas/ApplicationFormLevelEnum'
      required:
      - title
    EmploymentTypeA7aEnum:
      enum:
      - 1
      - 2
      - 3
      - 4
      - 5
      - 6
      - 7
      type: integer
      description: |-
        * `1` - 正社員
        * `2` - アルバイト・パート
        * `3` - 契約社員
        * `4` - 派遣社員
        * `5` - 臨時・期間従業員
        * `6` - 業務委託
        * `7` - インターンシップ
    JobAttribute:
      type: object
      description: |-
        求人属性の読み取り表現（registry 由来）。

        旧 ``JobAttribute`` モデル直結（ModelSerializer）から、registry を正本とする
        プレーン Serializer へ移行した（ADR-035 Phase 2）。フィールド構成は不変なので
        生成型（OpenAPI）の契約は維持される。実体の組み立ては
        ``JobPostingAttributeMappingSerializer._resolve_attribute`` が registry から行い、
        本クラスは主に出力スキーマの宣言に使う。
      properties:
        key:
          type: string
        label:
          type: string
        category:
          $ref: '#/components/schemas/CategoryEnum'
        category_display:
          type: string
        description:
          type: string
        display_order:
          type: integer
      required:
      - category
      - category_display
      - description
      - display_order
      - key
      - label
    JobImageUploadRequest:
      type: object
      description: 求人画像アップロードシリアライザー。
      properties:
        image:
          type: string
          format: binary
        alt_text:
          type: string
          maxLength: 255
        is_main:
          type: boolean
          default: false
      required:
      - image
    JobPostingAttributeMapping:
      type: object
      description: |-
        求人の per-job 属性 1 件分の読み取り表現（属性メタは registry で解決）。

        読取元は ``JobPosting.effective_attribute_ids``（provenance 別 3 カラムの和集合・
        生キー）で、``many=True`` の親が ``source="effective_attribute_ids"`` により
        生キー文字列を 1 件ずつ本シリアライザへ渡す（ADR-035 Phase 3 reader cutover）。
        中間表 ``JobPostingAttributeMapping`` には依存しない。廃止フィールドの
        ``detected_by`` / ``confidence`` は出力しない（API 形状から削除）。
      properties:
        attribute:
          allOf:
          - $ref: '#/components/schemas/JobAttribute'
          readOnly: true
      required:
      - attribute
    NullEnum:
      enum:
      - null
    PaginatedEmployerJobListList:
      type: object
      required:
      - results
      properties:
        next:
          type: string
          nullable: true
          format: uri
          example: http://api.example.org/accounts/?cursor=cD00ODY%3D"
        previous:
          type: string
          nullable: true
          format: uri
          example: http://api.example.org/accounts/?cursor=cj0xJnA9NDg3
        results:
          type: array
          items:
            $ref: '#/components/schemas/EmployerJobList'
    PatchedEmployerJobUpdateRequest:
      type: object
      description: 求人更新用シリアライザー。
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 255
        employment_type:
          nullable: true
          title: 雇用形態
          description: |-
            求人の雇用形態。正社員、アルバイト等。

            * `1` - 正社員
            * `2` - アルバイト・パート
            * `3` - 契約社員
            * `4` - 派遣社員
            * `5` - 臨時・期間従業員
            * `6` - 業務委託
            * `7` - インターンシップ
          minimum: -32768
          maximum: 32767
          oneOf:
          - $ref: '#/components/schemas/EmploymentTypeA7aEnum'
          - $ref: '#/components/schemas/NullEnum'
        location_prefecture:
          type: string
          title: 都道府県
          description: 勤務地の都道府県名
          maxLength: 50
        location_city:
          type: string
          title: 市区町村
          description: 勤務地の市区町村名
          maxLength: 100
        location:
          type: string
          title: 勤務地
          description: 勤務地の詳細情報
          maxLength: 500
        access:
          type: string
          title: 交通アクセス
          description: 最寄り駅からの徒歩分数、バス、車などの詳細アクセス情報
        salary_type:
          allOf:
          - $ref: '#/components/schemas/SalaryTypeEnum'
          title: 給与形態
        salary_annual_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 年収（最小）
          description: 円単位
        salary_annual_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 年収（最大）
          description: 円単位
        salary_monthly_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 月給（最小）
          description: 円単位
        salary_monthly_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 月給（最大）
          description: 円単位
        salary_hourly_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 時給（最小）
          description: 円単位
        salary_hourly_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 時給（最大）
          description: 円単位
        salary_daily_min:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 日給（最小）
          description: 円単位
        salary_daily_max:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
          title: 日給（最大）
          description: 円単位
        description:
          type: string
        working_hours:
          type: string
          title: 勤務時間
        holidays:
          type: string
          title: 休日・休暇
        employment_period:
          type: string
          title: 雇用期間
          maxLength: 500
        body_format:
          allOf:
          - $ref: '#/components/schemas/BodyFormatEnum'
          description: |-
            本文 (description / qualifications 等) のフォーマット。

            * `plain` - Plain
            * `markdown` - Markdown
        work_style_attribute_keys:
          type: array
          items:
            type: string
            minLength: 1
          writeOnly: true
        benefit_attribute_keys:
          type: array
          items:
            type: string
            minLength: 1
          writeOnly: true
        qualifications:
          type: string
        hiring_count:
          type: integer
          nullable: true
        benefits_text:
          type: string
        selection_process:
          type: string
        bonus:
          type: string
        allowances:
          type: string
        application_form_level:
          $ref: '#/components/schemas/ApplicationFormLevelEnum'
    PatchedJobImageUpdateRequest:
      type: object
      description: 求人画像更新シリアライザー。
      properties:
        is_main:
          type: boolean
        alt_text:
          type: string
          maxLength: 255
        display_order:
          type: integer
          minimum: 0
    PublicApiError:
      type: object
      properties:
        detail:
          type: string
          description: 人間可読のエラー説明。
        code:
          type: string
          description: '機械可読のエラーコード（例: not_authenticated, permission_denied, not_found,
            validation_error, throttled）。'
        errors:
          type: object
          additionalProperties: true
          description: フィールド単位のバリデーションエラー（該当時のみ）。
      required:
      - detail
      - code
    SalaryTypeEnum:
      enum:
      - ANNUAL
      - MONTHLY
      - DAILY
      - HOURLY
      - FULL_COMMISSION
      type: string
      description: |-
        * `ANNUAL` - 年収
        * `MONTHLY` - 月給
        * `DAILY` - 日給
        * `HOURLY` - 時給
        * `FULL_COMMISSION` - 完全歩合制
    SourceAcquisitionMethodEnum:
      enum:
      - direct
      - api
      - crawled
      - feed_import
      type: string
      description: |-
        * `direct` - Direct Posting
        * `api` - API Partner
        * `crawled` - Crawled
        * `feed_import` - Feed Import
    Status5b9Enum:
      enum:
      - draft
      - awaiting_review
      - published
      - expired
      - filled
      - rejected
      type: string
      description: |-
        * `draft` - 下書き
        * `awaiting_review` - Awaiting Review
        * `published` - Published
        * `expired` - Expired
        * `filled` - Filled
        * `rejected` - Rejected
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: 'Employer 公開API 用。ヘッダに `Authorization: Api-Key <平文キー>` を指定する。キーはダッシュボードの
        Security 設定から発行可能。'
tags: []
servers:
- url: https://jobmore.co.jp
  description: 本番環境
security:
- apiKeyAuth: []
