Skip to content

Cabin Analytics API ​

対象プランPlusScale

Cabinは、データにアクセスするための読み取り専用APIを提供しています。アナリティクスのレスポンスは集計済みのデータで(ダッシュボードでの保存・表示のされ方と同じです)、JSON形式で取得できます。

Freeプランでは、代わりにAI/MCPアクセスをお使いください。すべてのプランに含まれており、同じ質問に普段の言葉で答えられます。

APIキー ​

APIを使うには、アカウントのAPI keys(APIキー)の設定でAPIキーを作成する必要があります。

各キーは読み取り専用で、すべてのドメインを対象にすることも、特定のドメインに限定することもできます。

APIキーはAI/MCPアクセスには使いません。エージェントは代わりにOAuthでサインインするため、キーは一切不要です。

APIキーのセクション

  1. 'New Key' を選択します
  2. キーに名前を付けます
  3. アクセスを許可するドメインを選択します
  4. 'Create' をクリックします

認証 ​

リクエストを認証するには、リクエストのx-api-keyヘッダーにAPIキーを含める必要があります。

リクエストの例:

bash
curl -X GET "https://api.withcabin.com/v1/analytics?domain=example.com&date_from=2025-01-01&date_to=2025-02-01&scope=core&limit_lists=20" -H "x-api-key: YOUR_API_KEY"

エンドポイント ​

APIはhttps://api.withcabin.com/v1/{endpoint}で利用できます。

/analytics ​

このエンドポイントは、2つの日付の間のウェブサイトのトラフィックに関する集計データを返します。ページビューと直帰の日別集計データも含まれます。

クエリパラメーター ​

domain ​

string required

アナリティクスデータを取得したいドメイン名です。

date_from ​

string required

データの開始日です(形式:YYYY-MM-DD)。

date_to ​

string required

データの終了日です(形式:YYYY-MM-DD)。

scope ​

string optional

デフォルト:core。データの範囲です。core,pages,referrals,eventsを任意に組み合わせて指定できます。

limit_lists ​

number optional

デフォルト:50。各リストで返す項目数です。250を超える値も拒否はされませんが、レスポンスが大きく遅くなるため、実用上の上限は250と考えてください。

この値はcountries、languages、browsers、operating_systems、devices、screen_sizes、pages、referralsに適用されます。

レスポンス内のパーセンテージは、上限にかかわらずデータ全体を基準に計算されます。

scopeについて ​

pagesとreferralsのscopeを指定すると、ドメイン内の個々のパスについてのデータが追加されます(レスポンスの例をご覧ください)。これらは少し重いため、追加のデータが必要でなければcoreを使うことをおすすめします。

エネルギー排出量のデータは、pagesのscopeでのみ取得できます。

スクロール深度もpagesで取得でき、2か所に含まれます。各ページのscroll_depthオブジェクトと、トップレベルにあるサイト全体のscroll_depthです。サイト全体の値はlimit_listsを適用する前にすべてのページを合計したものなので、送られてきたページの合計とは一致しません。

eventsはカスタムイベントを返し、それぞれのイベントが発生したページの内訳も含みます。pagesと同じ元データを読み取るため、pages,eventsをまとめて指定しても、どちらか一方だけを指定した場合とコストは変わりません。

AIエージェントの内訳は、追加のリクエストなしでcoreに含まれて返ります。これらのヒットはsummary.page_viewsとは別に数えられ、課金対象にもならないため、ai_agentsはページビューの合計には加算されません。また、各percentageはトラフィック全体ではなく、エージェントのトラフィックに占める割合です。

レスポンスの例 ​

json
{
  query: {
    domain: "example.com",
    date_from: "2025-01-01",
    date_to: "2025-02-01",
    scope: "core,pages,referrals",
    limit_lists: 10
  },

  /* scope: core で取得可能 */

  summary: {
    page_views: 1959,
    unique_visitors: 1165,
    bounces: 817,
    bounce_rate: 0.29871244635193134
  },
  daily_data: [
    {
      timestamp: 1735689600000,
      page_views: 22,
      unique_visitors: 16,
      bounces: 12,
      bounce_rate: 0.75
    },
    {
      timestamp: 1735776000000,
      page_views: 29,
      unique_visitors: 26,
      bounces: 23,
      bounce_rate: 0.88
    },
    {
      timestamp: 1735862400000,
      page_views: 24,
      unique_visitors: 16,
      bounces: 13,
      bounce_rate: 0.81
    }
  ],
  screen_sizes: {
    small: 38,
    medium: 372,
    large: 463
  },
  devices: {
    desktop: 873,
    mobile: 288,
    tablet: 4,
    smart_tv: 0,
    console: 0,
    wearable: 0
  },
  browsers: [
    {
      name: "Chrome",
      value: 718
    },
    {
      name: "WebKit",
      value: 117
    },
    {
      name: "Firefox",
      value: 85
    }
  ],
  operating_systems: [
    {
      name: "Windows",
      value: 467
    },
    {
      name: "Mac OS",
      value: 365
    },
    {
      name: "iOS",
      value: 223
    }
    // ...
  ],
  countries: [
    {
      code: "GB",
      value: 362
    },
    {
      code: "US",
      value: 263
    },
    {
      code: "JP",
      value: 41
    }
    // ...
  ],
  languages: [
    {
    code: "en",
      value: 887
    },
    {
      code: "ja",
      value: 37
    },
    {
      code: "ru",
      value: 32
    }
    // ...
  ],
  traffic_sources: {
    email: 0,
    search: 217,
    social: 151,
    unknown: 789
  },
  ai_agents: [
    {
      name: "ChatGPT",
      hits: 34,
      percentage: 0.9444
    },
    {
      name: "Claude",
      hits: 2,
      percentage: 0.0556
    }
  ],

  /* scope: pages で取得可能 */

  energy: {
    page_count: 22,
    green_hosting: {
      url: "nicmulvaney.com",
      hosted_by: "Cloudflare",
      hosted_by_website: "https://www.cloudflare.com",
      partner: null,
      green: true,
      hosted_by_id: 779,
      modified: "2025-03-17T20:24:22",
      supporting_documents: [
        {
          id: 18,
          title: "Blog post - The Climate and Cloudflare",
          link: "https://blog.cloudflare.com/the-climate-and-cloudflare/"
        },
        {
          id: 1264,
          title: "Cloudflare 2023 Emissions Inventory",
          link: "https://s3.nl-ams.scw.cloud/tgwf-web-app-live/uploads/Cloudflare_2023_Emissions_Inventory.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=SCWT1WBAW6NZ5SW5GYJ8%2F20250317%2Fnl-ams%2Fs3%2Faws4_request&X-Amz-Date=20250317T202736Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=0d3b2ffd9a885dbc41193e0e72bdee9c4ee8cf37671af3d092453578cc5a179c"
        }
      ]
    },
    average_time_spent_ms: 122892,
    average_co2_grams: 0.0708,
    total_co2_grams: 138.65,
    total_distance_km: 0.55,
    total_kettles: 4,
    transferred_bytes: 1145572683,
    total_bytes: 22060595,
    duration_total_ms: 240746383,
    duration_count: 1272
  },
  pages: [
    {
      path: "/page/1",
      page_views: 271671,
      unique_visitors: 243070,
      average_duration_seconds: 123,
      total_bytes: 8.2,
      co2_grams: 538,
      page_views_percentage: 0.12,
      scroll_depth: {
        average_percentage: 46.2,
        measured_visits: 1840,
        reached_at_least: [
          { percent: 0, visitors_percentage: 100 },
          { percent: 10, visitors_percentage: 88.37 },
          { percent: 20, visitors_percentage: 79.08 },
          { percent: 30, visitors_percentage: 73.75 },
          { percent: 40, visitors_percentage: 69.18 },
          { percent: 50, visitors_percentage: 65 },
          { percent: 60, visitors_percentage: 57.83 },
          { percent: 70, visitors_percentage: 52.61 },
          { percent: 80, visitors_percentage: 46.63 },
          { percent: 90, visitors_percentage: 38.86 },
          { percent: 100, visitors_percentage: 22.01 }
        ]
      }
    },
    {
      path: "/page/2",
      page_views: 167111,
      unique_visitors: 150073,
      average_duration_seconds: 147,
      total_bytes: 4.82,
      co2_grams: 222.6,
      page_views_percentage: 0.08
    },
    {
      path: "/page/3",
      page_views: 106361,
      unique_visitors: 93743,
      average_duration_seconds: 97,
      total_bytes: 4.82,
      co2_grams: 133.4,
      page_views_percentage: 0.05
    },
    // ...
  ],

  // サイト全体の値。`pages` に含まれるページだけでなく、すべてのページの合計。
  scroll_depth: {
    average_percentage: 41.8,
    measured_visits: 94211,
    reached_at_least: [
      { percent: 0, visitors_percentage: 100 },
      // ... 10%ごとに1行 ...
      { percent: 100, visitors_percentage: 18.4 }
    ]
  },

  /* scope: referrals で取得可能 */

  referrals: [
    {
      source: "Google",
      page_views: 259,
      unique_visitors: 197,
      has_utm: false,
      page_views_percentage: 0.39
    },
    {
      source: "LinkedIn",
      page_views: 252,
      unique_visitors: 136,
      has_utm: false,
      page_views_percentage: 0.38
    },
    {
      source: "com.linkedin.android",
      page_views: 34,
      unique_visitors: 18,
      has_utm: false,
      page_views_percentage: 0.05
    },
    // ...
  ],

  /* scope: events で取得可能 */

  events: [
    {
      name: "signup button (header)",
      count: 14,
      percentage: 0.1129,
      pages: [
        {
          path: "/",
          count: 13,
          percentage: 0.9286
        },
        {
          path: "/pricing",
          count: 1,
          percentage: 0.0714
        }
      ]
    },
    // ...
  ]
}

scroll_depthの読み方 ​

average_percentageは到達した最も深い位置の平均値で、measured_visitsはその平均値の算出に使われた訪問数です。これは常にサンプルです。値は訪問者がページを離れるときに送信されますが、ブラウザによってはスクリプトにその機会を与えないため、measured_visitsはpage_viewsより少なく、大きく下回ることもよくあります。

reached_at_leastは累積値です。各行は、計測された訪問のうち、ページのその位置まで少なくとも到達した割合を示します。そのためpercent: 0は常に100で、そこから先の行は下がる一方です。2つの行の間で値が下がったところが、訪問者が読むのをやめた位置です。

js
// 「ページの半分を超えて読んだ割合は?」
const half = page.scroll_depth.reached_at_least.find(r => r.percent === 50)
console.log(half.visitors_percentage) // 65

深さはドキュメント全体ではなく、ページのコンテンツブロックを基準に計測されます。そのため、フッターが長くても、最後まで読んだ訪問が75%のように見えることはありません。100%に到達したというのは、コンテンツの一番下が画面に表示されたという意味で、読まれたという意味ではありません。コンテンツブロックの見つけ方や自分でタグ付けする方法は、スクロール深度をご覧ください。

scroll_depthがないことは「計測されていない」という意味で、ゼロではありません。 画面より短いページはスクロールするものがないため除外されます。訪問がすべてこの機能の導入前のページも同様です。値を読み取る前に、キーがあるかどうかを確認してください。

プランによる制限 ​

返ってくる内容はプランによって変わります。

  • 保存期間。 date_fromはプランの保存期間(Plusは12か月、Scaleは無制限)に合わせて調整されます。それより古いデータを求めても、エラーではなく、まだ残っている最も古いデータが返ります。
  • エネルギーデータ。 energyブロックとページごとのCO₂の数値には、PlusとScaleで使えるCO₂レポートが必要です。
  • カスタムイベント。 eventsブロックはPlusとScaleで使えます。
  • AIエージェント。 ai_agentsブロックはScaleで使えます。
  • スクロール深度。 Freeを含むすべてのプランで使えます。

利用資格のないブロックは、空で返されるのではなくレスポンスから省かれます。読み取る前にキーがあるかどうかを確認してください。

フェアユース ​

リクエストは常識的な頻度、目安として1分あたり20回程度に抑えてください。データは日単位で集計されるため、それより頻繁にポーリングしても新しい情報は得られません。より高い頻度が必要な場合は、お問い合わせください。