> ## 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.

# 取引を作成

> 新しい取引を作成する。レスポンスの `id`(record_id)を保存し、以降の参照・更新に使う。




## OpenAPI

````yaml /openapi/v1.yaml post /v1/deals/
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/deals/:
    post:
      tags:
        - Deals
      summary: 取引を作成
      description: |
        新しい取引を作成する。レスポンスの `id`(record_id)を保存し、以降の参照・更新に使う。
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DealCreateRequest'
      responses:
        '201':
          description: 作成成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Deal'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
      security:
        - BearerApiKey: []
components:
  schemas:
    DealCreateRequest:
      type: object
      required:
        - properties
      properties:
        properties:
          type: object
          required:
            - name
          properties:
            name:
              type: string
              minLength: 1
              description: 取引名(Stockwork 必須)
          additionalProperties:
            $ref: '#/components/schemas/PropertyValue'
      example:
        properties:
          name: 株式会社サンプル 新規導入
          amount: 5000000
          close_date: '2026-09-30'
          stage: proposal
    Deal:
      type: object
      description: 取引(Deal)レコード
      properties:
        id:
          type: string
          description: Stockwork record_id(18 文字)。クライアントはこの ID を保存して以降の参照に使う。
          example: Rb7XkQpYz3Lh9vMs2N
        properties:
          allOf:
            - $ref: '#/components/schemas/PropertiesMap'
          description: |
            取引のプロパティ集合。`name` は必須。
            `amount`/`close_date`/`stage` 等のコアフィールドと、組織別カスタムプロパティが
            同じ namespace で扱われる。

            リレーションは record_id 文字列で表す。
            - `account_id` — 商談先の会社(Account)
            - `owner_id` — 担当ユーザー(User)。`GET /v1/users/` で解決する
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
          description: >-
            レコードの値が最後に変わった日時。コアフィールド・カスタムプロパティ・アクティビティ件数などの集計値のいずれかが実際に変わったときに進む。商談ログやメールなどの活動を記録した場合も、それが集計値を動かすためこの日時が進む。同じ値での再保存や、他レコードとの紐付け変更では進まない。
      required:
        - id
        - properties
        - created_at
        - updated_at
      example:
        id: Rb7XkQpYz3Lh9vMs2N
        properties:
          name: 株式会社サンプル 新規導入
          amount: 5000000
          close_date: '2026-09-30'
          stage: proposal
          account_id: Ac7XkQpYz3Lh9vMs2N
          owner_id: Us7XkQpYz3Lh9vMs2N
        created_at: '2026-06-01T09:00:00Z'
        updated_at: '2026-06-12T05:40:00Z'
    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
    PropertiesMap:
      type: object
      description: |
        プロパティの集合。キーは `api_name`、値は `PropertyValue`。
        コアフィールドと組織別カスタムプロパティが同じ namespace に並ぶ。
        利用可能なキーと型は `GET /v1/<resource>/properties/` で取得する。
      additionalProperties:
        $ref: '#/components/schemas/PropertyValue'
    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: この項目は必須です。
    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
  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 参照)。

````