> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stockwork.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 会社を検索(フィルタ + 自由文字列 + ソート + ページネーション)

> GUI 一覧画面と同等の表現力で会社を検索する。必要 role: `read`。




## OpenAPI

````yaml /openapi/v1.yaml post /v1/companies/search/
openapi: 3.0.3
info:
  title: Stockwork Public API
  version: 1.0.0
  description: >
    Stockwork の取引(Deal)・会社(Account)・コンタクト(Contact)・商談ログ(Meeting Log)・

    コンタクト活動(Contact Activity)を外部システムから操作する公開 API。


    ## 認証

    `Authorization: Bearer sk_<base62>` 形式の API キーを送る。

    キーは Stockwork 管理画面で発行し、発行時のみ平文が 1 回だけ返却される(以降は再表示不可)。


    ## 識別子

    Stockwork が発行する `id`(record_id、18 文字)が**全レコードの唯一の identity**。

    クライアントはこの `id` を保存し、以降の取得・更新に使用する。


    レコード間の参照もすべて record_id で行う。`properties.account_id`(Contact → Account)、

    `properties.deal_id`(Meeting Log → Deal)、`properties.contact_id`(Contact
    Activity →

    Contact)、`properties.owner_id`(Deal → User)。担当ユーザーの氏名・メールアドレスは

    `GET /v1/users/` で解決する。


    メールアドレスから担当者の record_id を引きたい場合は `GET /v1/users/?email=...` を使う。

    ただしこれは**発見用のフィルタであって識別子ではない**。メールアドレスは変更され得るため、

    解決した record_id を保存して以降の参照に使うこと(HubSpot / Salesforce と同じ作法)。


    ## エラー

    全てのエラーは次の封筒で返る。`error.code` は機械可読な enum、`error.message` は人間向けの

    説明文(日本語)。バリデーション失敗時のみ `error.fields` にフィールド単位の詳細が入る。


    ```json

    {
      "error": {
        "code": "validation_error",
        "message": "リクエストの検証に失敗しました。",
        "fields": [
          {"name": "properties.name", "code": "required", "message": "この項目は必須です。"}
        ]
      }
    }

    ```


    ## ロール

    API キー発行時に付与する **role** で操作範囲を制限する。Stockwork 既存の組織ロールと

    同じ概念を流用(リソース単位の細かいスコープ分割は提供しない):

    - `read` — 読み取りのみ

    - `analyst` — 読み取り + 分析(本 API では read 相当)

    - `write` — 読み取り + 書き込み

    - `admin` — 全権限


    ### エンドポイントと必要 role の対応

    | メソッド + パス | 必要 role |

    |---|---|

    | `GET /v1/deals/` / `/v1/deals/{record_id}/` / `/v1/deals/properties/` |
    `read` |

    | `POST /v1/deals/search/` | `read` |

    | `POST /v1/deals/` / `PATCH /v1/deals/{record_id}/` | `write` |

    | `GET /v1/companies/` / `/v1/companies/{record_id}/` /
    `/v1/companies/properties/` | `read` |

    | `POST /v1/companies/search/` | `read` |

    | `POST /v1/companies/` / `PATCH /v1/companies/{record_id}/` | `write` |

    | `GET /v1/contacts/` / `/v1/contacts/{record_id}/` /
    `/v1/contacts/properties/` | `read` |

    | `POST /v1/contacts/search/` | `read` |

    | `POST /v1/contacts/` / `PATCH /v1/contacts/{record_id}/` | `write` |

    | `GET /v1/meeting-logs/` / `/v1/meeting-logs/{record_id}/` /
    `/v1/meeting-logs/properties/` | `read` |

    | `POST /v1/meeting-logs/search/` | `read` |

    | `POST /v1/meeting-logs/` / `PATCH /v1/meeting-logs/{record_id}/` | `write`
    |

    | `GET /v1/contact-activities/` / `/v1/contact-activities/{record_id}/` /
    `/v1/contact-activities/properties/` | `read` |

    | `POST /v1/contact-activities/search/` | `read` |

    | `POST /v1/contact-activities/` / `PATCH
    /v1/contact-activities/{record_id}/` | `write` |

    | `GET /v1/users/` / `/v1/users/{record_id}/` | `read` |


    上位 role は下位 role を内包する(`write` キーは `read` 操作も可)。


    ## 検索(プロパティ値による絞り込み)

    GUI 一覧画面と同等の表現力でレコードを検索できる `POST /v1/<resource>/search/`

    を提供する。クエリ文字列ではなく POST body にフィルタを含めるため、WAF / 中間機器の

    URL 長制限の影響を受けない。


    - **2 階層構造**: グループ間 OR / グループ内 AND(GUI と同じ。最大 10 グループ)

    - **対象フィールド**: コアフィールド(`name` / `amount` / `stage` 等)+ カスタム
      プロパティ(`PropertyDefinition.api_name` で指定)
    - **operator**: text / number / date / select / boolean のそれぞれに必要な集合を提供
      (詳細は `FilterOperator` schema)
    - **select 値の解決**: ラベルではなく**内部値の完全一致**のみ(fuzzy match なし)

    - **`is_null` / `is_empty` の意味論**: 該当プロパティの値レコードが存在しない場合も
      含める(GUI と同じ)
    - **ページネーション**: 検索はページ番号型(`page` / `page_size`)。任意の複合ソート
      (`sort_by` / `sort_order`)を許すため、カーソル型とは両立しない。
      `page * page_size` は **10,000 を超えられない**(超過時は `400`)。
      全件走査には `GET /v1/<resource>/?updated_after=...` のカーソルページネーションを使う。

    ## `updated_at` と差分取得


    `updated_at` は**レコードの値が最後に変わった日時**で、行への書き込み日時ではない。

    コアフィールド・カスタムプロパティ・アクティビティ件数などの集計値のいずれかが実際に

    変わったときに進む。商談ログやメールを記録した場合も、それが集計値を動かすため進む。


    同じ値での再保存（SFA 同期が同一値を書き戻した場合を含む）、他レコードとの紐付け変更、

    日次バッチが再計算する予測値（受注確率・ヘルススコア）では進まない。


    `updated_after` を差分同期のウォーターマークに使う場合、活動の記録でも親レコードが

    再取得対象になる点に注意する。


    ## レート制限

    - API キー単位: `1000 / 分`

    - 組織合算: `5000 / 分`


    全レスポンス(成功・失敗を問わず)に次のヘッダを付与する。クライアントは残量を見て

    事前に減速できる。


    - `X-RateLimit-Limit` — 現在の窓の上限回数(API キー単位)

    - `X-RateLimit-Remaining` — 現在の窓の残り回数

    - `X-RateLimit-Reset` — 窓がリセットされる Unix 時刻(秒)


    超過時は `429 Too Many Requests` + `Retry-After` ヘッダ。
  contact:
    name: Stockwork Public API Support
servers:
  - url: https://api.strixai.jp
    description: Production
  - url: https://api-dev.strixai.jp
    description: Development(検証環境)
security:
  - BearerApiKey: []
tags:
  - name: Deals
    description: 取引リソース
  - name: Companies
    description: 会社(Account)リソース
  - name: Contacts
    description: コンタクトリソース
  - name: Meeting Logs
    description: 商談ログ(Deal 配下の活動)リソース
  - name: Contact Activities
    description: コンタクト活動(Contact 配下の活動)リソース
  - name: Users
    description: Stockwork ユーザー(担当者)リソース。read-only
paths:
  /v1/companies/search/:
    post:
      tags:
        - Companies
      summary: 会社を検索(フィルタ + 自由文字列 + ソート + ページネーション)
      description: |
        GUI 一覧画面と同等の表現力で会社を検索する。必要 role: `read`。
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SearchRequest'
      responses:
        '200':
          description: 検索成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccountListResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
      security:
        - BearerApiKey: []
components:
  schemas:
    SearchRequest:
      type: object
      description: |
        検索リクエストの共通 schema。
        フィルタ・自由文字列・ソート・ページネーションを一括で受け付ける。
      properties:
        filter_groups:
          type: array
          maxItems: 10
          description: |
            フィルタグループの配列。**グループ間は OR で結合**(GUI と同じ意味論)。
            グループ内の `conditions` は AND。最大 10 グループまで。
            空配列または省略時は全レコードが対象。

            「複数フィールドへの横断キーワード検索」(GUI の検索ボックス相当)も、
            複数グループに同じ値の `contains` 条件を入れて表現できる(`search` のような
            専用フィールドは提供しない)。
          items:
            $ref: '#/components/schemas/FilterGroup'
        sort_by:
          type: array
          items:
            type: string
          description: |
            ソート対象のフィールド(複数指定でセカンダリーソート)。
            例: `["close_date", "amount"]`
        sort_order:
          type: array
          items:
            type: string
            enum:
              - asc
              - desc
          description: |
            ソート順。`sort_by` と同じ長さで指定する。
            例: `["asc", "desc"]`
        page:
          type: integer
          minimum: 1
          default: 1
          description: |
            ページ番号(1 始まり)。
            `page * page_size` が 10,000 を超える指定は `400` で拒否される
            (深い OFFSET 走査の防止)。全件走査にはリスト GET のカーソルを使う。
        page_size:
          type: integer
          minimum: 1
          maximum: 200
          default: 100
          description: 1 ページあたりの件数
    AccountListResponse:
      type: object
      properties:
        results:
          type: array
          items:
            $ref: '#/components/schemas/Account'
        paging:
          $ref: '#/components/schemas/Paging'
      required:
        - results
        - paging
    FilterGroup:
      type: object
      description: |
        フィルタ条件のグループ。グループ内の `conditions` は **AND** で結合される。
      required:
        - conditions
      properties:
        name:
          type: string
          description: 任意のグループ名(検索ロジックには影響しない。クライアント側の整理用)
          example: 高額の継続中案件
        conditions:
          type: array
          minItems: 1
          description: グループ内の条件配列(AND 結合)
          items:
            $ref: '#/components/schemas/FilterCondition'
    Account:
      type: object
      description: 会社(Account)レコード
      properties:
        id:
          type: string
          description: Stockwork record_id(18 文字)
          example: Ac7XkQpYz3Lh9vMs2N
        properties:
          allOf:
            - $ref: '#/components/schemas/PropertiesMap'
          description: |
            会社のプロパティ集合。`name` は必須。
            `industry`/`employees`/`phone`/`website`/`billing_*` 等のコアフィールドと
            カスタムプロパティが同じ namespace。
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
          description: >-
            レコードの値が最後に変わった日時。コアフィールド・カスタムプロパティ・アクティビティ件数などの集計値のいずれかが実際に変わったときに進む。商談ログやメールなどの活動を記録した場合も、それが集計値を動かすためこの日時が進む。同じ値での再保存や、他レコードとの紐付け変更では進まない。
      required:
        - id
        - properties
        - created_at
        - updated_at
      example:
        id: Ac7XkQpYz3Lh9vMs2N
        properties:
          name: 株式会社サンプル
          industry: IT
          employees: 120
          website: https://example.co.jp
        created_at: '2026-05-20T09:00:00Z'
        updated_at: '2026-06-10T03:00:00Z'
    Paging:
      type: object
      description: ページネーション情報
      properties:
        next:
          type: object
          nullable: true
          description: 次ページが無いときは null
          properties:
            after:
              type: string
              description: 次ページ取得用カーソル
            link:
              type: string
              format: uri
              description: 次ページの完全 URL
          required:
            - after
            - link
    Error:
      type: object
      description: |
        全エラーレスポンスの共通封筒。
      properties:
        error:
          type: object
          properties:
            code:
              $ref: '#/components/schemas/ErrorCode'
            message:
              type: string
              description: 人間向けの説明文(日本語)
            fields:
              type: array
              description: |
                `code` が `validation_error` のときのみ存在。フィールド単位の詳細。
              items:
                $ref: '#/components/schemas/FieldError'
          required:
            - code
            - message
      required:
        - error
      example:
        error:
          code: validation_error
          message: リクエストの検証に失敗しました。
          fields:
            - name: properties.name
              code: required
              message: この項目は必須です。
    FilterCondition:
      type: object
      description: |
        検索条件の最小単位。「どのフィールド」「どの演算子」「どの値」で絞り込むかを表す。
      required:
        - field
        - operator
      properties:
        field:
          type: string
          description: |
            検索対象のフィールド名。
            - **コアフィールド**: `name` / `amount` / `stage` / `close_date` 等、リソースの
              直接カラムを名前で指定。
            - **カスタムプロパティ**: `GET /v1/<resource>/properties/` で取得した
              `api_name`(8 文字英数字)を指定。
          example: amount
        operator:
          $ref: '#/components/schemas/FilterOperator'
        value:
          description: >
            operator に応じた値。型は operator が要求する形式に合わせる。

            - 単一値型 (`equals` / `eq` / `contains` 等): string / number / boolean
            のいずれか

            - 範囲型 (`range` / `date_range`): `[from, to]` の 2 要素配列

            - 複数値型 (`in` / `not_in`): string / number の配列

            - 値不要 (`is_null` / `is_not_null` / `is_empty` / `is_not_empty`):
            省略する
          oneOf:
            - type: string
            - type: number
            - type: boolean
            - type: array
              items:
                oneOf:
                  - type: string
                  - type: number
    PropertiesMap:
      type: object
      description: |
        プロパティの集合。キーは `api_name`、値は `PropertyValue`。
        コアフィールドと組織別カスタムプロパティが同じ namespace に並ぶ。
        利用可能なキーと型は `GET /v1/<resource>/properties/` で取得する。
      additionalProperties:
        $ref: '#/components/schemas/PropertyValue'
    ErrorCode:
      type: string
      description: |
        機械可読なエラー種別。HTTP ステータスと 1 対 1 ではない(`400` は
        `validation_error` と `invalid_request` の両方を取り得る)ため、
        クライアントは**このコードで分岐する**こと。
        今後の追加に備え、未知のコードは汎用エラーとして扱うこと。
      enum:
        - invalid_request
        - validation_error
        - unauthorized
        - forbidden
        - not_found
        - rate_limited
        - internal_error
    FieldError:
      type: object
      description: バリデーション失敗時のフィールド単位の詳細
      properties:
        name:
          type: string
          description: 対象フィールドのパス。`properties` 配下は `properties.<api_name>` で表す
          example: properties.name
        code:
          type: string
          description: >
            フィールド単位のエラー種別。

            `required` / `invalid_type` / `invalid_value` / `not_found` /
            `unknown_property` /

            `too_long` / `out_of_range` のいずれか。
          example: required
        message:
          type: string
          description: 人間向けの説明文(日本語)
          example: この項目は必須です。
      required:
        - name
        - code
        - message
    FilterOperator:
      type: string
      description: >
        フィールド検索の比較演算子。プロパティ型ごとに利用可能な集合が異なる(下記)。

        利用不可な組み合わせは `400 Bad Request` で拒否される。


        - **text** (CharField / TextField): `contains` / `not_contains` /
        `equals` /
          `not_equals` / `is_empty` / `is_not_empty`
          (`contains` / `equals` はいずれも **case-insensitive** で動作)
        - **number** (DecimalField / IntegerField): `eq` / `ne` / `gt` / `gte` /
        `lt` /
          `lte` / `range` / `is_null` / `is_not_null`
        - **date / datetime**: `date_eq` / `date_ne` / `date_after` /
        `date_before` /
          `date_on_or_before` / `date_on_or_after` / `date_range` / `is_null` /
          `is_not_null`
        - **select**: `equals` / `not_equals` / `in` / `not_in` / `is_null` /
          `is_not_null`(値は **PropertyOption の内部値**を指定。ラベルでの fuzzy
          match は提供しない)
        - **boolean**: `eq` / `ne` / `is_null` / `is_not_null`


        **`is_null` / `is_empty` の意味論**: 該当プロパティの値レコードがそもそも存在

        しないエンティティも結果に含める(GUI 検索と同じ動作)。
      enum:
        - contains
        - not_contains
        - equals
        - not_equals
        - is_empty
        - is_not_empty
        - is_null
        - is_not_null
        - eq
        - ne
        - gt
        - gte
        - lt
        - lte
        - range
        - in
        - not_in
        - date_eq
        - date_ne
        - date_after
        - date_before
        - date_on_or_before
        - date_on_or_after
        - date_range
    PropertyValue:
      description: |
        プロパティの値。文字列・数値・真偽値・null のいずれか。

        - **キーを送らない** = そのプロパティは変更しない(PATCH は部分更新)
        - **明示的に `null` を送る** = そのプロパティの値をクリアする

        作成(`POST`)時の `null` は「値なしで作成」と同義。
        必須プロパティに `null` を送った場合は `400`。

        (OpenAPI 3.0 では union に null 型を直接書けないため、`anyOf` の各分岐に
        `nullable: true` を付けて表現している。`oneOf` にすると null が全分岐にマッチして
        「ちょうど 1 つ」の条件を満たせない。)
      anyOf:
        - type: string
          nullable: true
        - type: number
          nullable: true
        - type: boolean
          nullable: true
  responses:
    BadRequest:
      description: バリデーション失敗
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: 認証失敗(キー欠落・不正・失効・IP 拒否)
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: スコープ不足
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    TooManyRequests:
      description: レート制限超過(`Retry-After` ヘッダあり)
      headers:
        Retry-After:
          schema:
            type: integer
          description: 次のリクエストまでの待機秒数
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    BearerApiKey:
      type: http
      scheme: bearer
      bearerFormat: sk_*
      description: |
        Stockwork が発行する API キー(`sk_` プレフィックス、base62 ランダム ≥ 40 文字)。
        キーには 1 つの role(`read` / `analyst` / `write` / `admin`)が紐付き、
        各エンドポイントの必要 role 以上であることが要求される(対応表は info.description 参照)。

````