外部連携API仕様(GraphQL)

概要

DRIVE SFA は外部システム向けに GraphQL API を提供しています。取引先・取引先担当者・案件・営業活動のデータを外部プログラムから読み取り・書き込みすることができます。

NOTE

この機能は開発者向けです。利用にはサービスアカウントの発行が必要です。

  • エンドポイント:/graphql
  • プロトコル:GraphQL over HTTP (POST)
  • 認証:PAT(Personal Access Token)

このAPIでできること

操作対象データ
一覧取得・検索取引先 / 取引先担当者 / 案件 / 営業活動
詳細取得取引先 / 取引先担当者 / 案件
新規作成取引先 / 取引先担当者 / 案件 / 営業活動
更新取引先 / 取引先担当者 / 案件
削除(論理)取引先 / 取引先担当者 / 案件

活用事例

📥 他システムからDRIVE SFAへデータを取り込む

  • 名刺管理サービス:名刺読み取り後に取引先・担当者を自動登録
  • MAツール連携:フォーム入力された見込み客を取引先担当者として登録し、案件を自動生成
  • CTIシステム連携:通話終了後に createActivity(type: CALL) で電話活動を自動記録

📤 DRIVE SFAのデータを外部システムへ連携する

  • 社内BI / レポートツール連携:案件・営業活動データを定期的に取得してダッシュボードに反映
  • 基幹システム同期:成約した案件(contractStatusId: 2)を取得して受注処理へ連携
  • SFAデータ一括エクスポート:updatedSince で差分取得してデータウェアハウスへ同期

🔄 双方向連携

  • CRS / ERPとの双方向同期:externalId(外部連携ID)フィールドを利用して各システム間でレコードを関連付け。DRIVE SFA側の変更と外部システム側の変更を相互に反映

認証

Personal Access Token(PAT)

GraphQL APIはサービスアカウントに発行したPATで認証します。

  • リクエストヘッダーに Authorization: Bearer <token> を付与してください
  • PATはサービスアカウント単位で発行・失効・削除できます
  • PATには有効期限(expiresAt)を設定できます。未設定の場合は無期限です
  • トークンの平文は発行時1回のみ返却されます。再表示はできません

レート制限

各PATにはリクエスト数の上限があります。

  • 上限を超えた場合、HTTP ステータスは 200 のままですが、レスポンスボディの errors フィールドにレート制限エラーが返ります(GraphQL仕様のため)
  • レスポンスヘッダーで現在の制限状況を確認できます:
ヘッダー内容
X-RateLimit-Limit上限リクエスト数
X-RateLimit-Remaining残りリクエスト数
X-RateLimit-Reset制限リセット時刻(UNIXタイムスタンプ)
Retry-After次にリクエスト可能になるまでの秒数(超過時のみ)

ページネーション

一覧取得クエリは Relay Cursor Connections 仕様に準拠したカーソルベースのページネーションを採用しています。

引数説明
first前方からn件取得
afterfirst と組み合わせて使用するカーソル
last後方からn件取得
beforelast と組み合わせて使用するカーソル
  • firstlast を同時に指定することはできません
  • デフォルトは 10件、最大 100件
  • カーソルはレスポンスの edges[].cursor および pageInfo.startCursor / pageInfo.endCursor から取得します

Query(データ取得)

取引先

# 取引先一覧
query {
  accounts(
    name: String         # 取引先名(部分一致)
    externalId: String   # 外部連携ID(完全一致)
    updatedSince: String # この日時以降に更新されたもの(ISO8601形式)
    first: Int
    after: String
    last: Int
    before: String
  ) {
    edges {
      cursor
      node {
        id name nameKana tel email representativeContact
        webSite zipCode prefectureKindId city address
        externalId createdAt updatedAt lastUpdatedUserId lastActionDate
        properties { name value }
        contacts(first: Int, after: String) { edges { node { id name } } pageInfo { ... } }
        deals(first: Int, after: String) { edges { node { id name } } pageInfo { ... } }
        activities(first: Int, after: String) { edges { node { id type } } pageInfo { ... } }
      }
    }
    pageInfo { hasNextPage hasPreviousPage startCursor endCursor }
  }
}

# 取引先詳細
query {
  account(id: "123") {
    id name ...
  }
}

取引先担当者

query {
  contacts(
    accountId: String   # 取引先IDでフィルタ
    email: String       # メールアドレス(部分一致)
    externalId: String  # 外部連携ID(完全一致)
    first: Int  after: String  last: Int  before: String
  ) {
    edges {
      cursor
      node {
        id accountId name nameKana department position
        phoneNumber email dateOfBirth isKeyPerson note
        externalId createdAt updatedAt
        properties { name value }
      }
    }
    pageInfo { ... }
  }
}

query { contact(id: "456") { id name ... } }

案件

query {
  deals(
    accountId: String    # 取引先IDでフィルタ
    stage: Long          # 契約ステータスID(1:進行中 / 2:成約 / 3:失注)
    ownerUserId: Long    # 担当ユーザーIDでフィルタ
    updatedSince: String # この日時以降に更新されたもの(ISO8601形式)
    externalId: String   # 外部連携ID(完全一致)
    first: Int  after: String  last: Int  before: String
  ) {
    edges {
      cursor
      node {
        id accountId name estimatedAmount startDate scheduledDate
        contractStatusId contractSignedDate contractCanceledDate
        contractCanceledAmount contractCanceledReason
        projectFlowId projectStepId note
        externalId createdAt updatedAt lastUpdatedUserId
        properties { name value }
        activities(first: Int, after: String) { edges { node { id type } } pageInfo { ... } }
      }
    }
    pageInfo { ... }
  }
}

query { deal(id: "789") { id name ... } }

営業活動

query {
  activities(
    accountId: String   # 取引先IDでフィルタ
    dealId: String      # 案件IDでフィルタ
    type: ActivityType  # 活動タイプでフィルタ(下記参照)
    since: String       # この日時以降の活動(ISO8601形式)
    first: Int  after: String  last: Int  before: String
  ) {
    edges {
      cursor
      node {
        id type accountId dealId contactId occurredAt
        summary detail externalSystem externalId createdAt
        properties { name value }
      }
    }
    pageInfo { ... }
  }
}

Mutation(データ書き込み)

取引先

# 作成
mutation { createAccount(input: {
  name: String!        # 必須
  nameKana: String  tel: String  email: String
  representativeContact: String  webSite: String
  zipCode: String  prefectureKindId: Long  city: String  address: String
  properties: [PropertyInput]
}) { id name ... } }

# 更新(未指定フィールドは既存値を維持)
mutation { updateAccount(input: {
  id: String!
  name: String  nameKana: String  ...(各フィールド任意)
  properties: [PropertyInput]
}) { id name ... } }

# 削除(論理削除)
mutation { deleteAccount(id: "123") }  # 削除されたIDを返す
# ⚠️ 取引先に紐づく案件もすべて論理削除されます

取引先担当者

mutation { createContact(input: {
  accountId: String!  name: String!
  nameKana: String  department: String  position: String
  phoneNumber: String  email: String  dateOfBirth: String
  isKeyPerson: Boolean  note: String
  properties: [PropertyInput]
}) { id name ... } }

mutation { updateContact(input: { id: String!, ... }) { id name ... } }

mutation { deleteContact(id: "456") }

案件

mutation { createDeal(input: {
  accountId: String!  name: String!  projectFlowId: Long!  projectStepId: Long!
  contractStatusId: Long!  estimatedAmount: Long
  startDate: String  scheduledDate: String  note: String
  userIds: [Long]  contactIds: [Long]  productIds: [Long]
  properties: [PropertyInput]
}) { id name ... } }

mutation { updateDeal(input: { id: String!, ... }) { id name ... } }

mutation { deleteDeal(id: "789") }

営業活動

# 作成のみ(更新・削除はGraphQL APIでは未提供)
mutation { createActivity(input: {
  accountId: String!  type: ActivityType!  occurredAt: String!  # ISO8601形式
  idempotencyKey: String!  # 重複登録防止キー(同一キーで再送した場合は既存を返す)
  dealId: String  contactId: String
  summary: String  detail: String
  externalSystem: String  externalId: String
  properties: [PropertyInput]
}) { id type occurredAt ... } }

型定義

ActivityType(営業活動タイプ)

説明
MEETING打ち合わせ
NEGOTIATION商談
CALL電話
EMAILメール
OTHERその他(タスク等)

契約ステータスID(案件)

説明
1進行中
2成約
3失注

PropertyInput(カスタム項目)

input PropertyInput {
  name: String!   # カスタム項目の物理名
  value: String   # 値
}

注意事項

CAUTION

deleteAccount は子案件も自動削除します:deleteAccount を実行すると、その取引先に紐づく全案件が自動的に論理削除されます。案件データが必要な場合は削除前に確認してください。

NOTE

論理削除:deleteAccount / deleteContact / deleteDeal はすべて論理削除です。削除されたIDが返り値として返されます。

NOTE

レート制限エラーはHTTP 200で返ります:GraphQLの仕様上、レート制限超過時もHTTPステータスは 200 です。エラー内容はレスポンスボディの errors フィールドで確認してください。

NOTE

冪等性:createActivityidempotencyKey をサポートします。同じキーで再送した場合は新規作成を行わず、既存の活動履歴を返します。外部システムとの連携時の重複登録防止に活用してください。

NOTE

カスタム項目:各 Mutation の properties 引数は省略可能です。省略した場合、既存のカスタム項目値は変更されません。

関連記事

この記事は役に立ちましたか?

解決しない場合はサポートへお問い合わせください