Cabin Analytics API
Cabinは、データにアクセスするための読み取り専用APIを提供しています。アナリティクスのレスポンスは集計済みのデータで(ダッシュボードでの保存・表示のされ方と同じです)、JSON形式で取得できます。
Freeプランでは、代わりにAI/MCPアクセスをお使いください。すべてのプランに含まれており、同じ質問に普段の言葉で答えられます。
APIキー
APIを使うには、アカウントのAPI keys(APIキー)の設定でAPIキーを作成する必要があります。
各キーは読み取り専用で、すべてのドメインを対象にすることも、特定のドメインに限定することもできます。
APIキーはAI/MCPアクセスには使いません。エージェントは代わりにOAuthでサインインするため、キーは一切不要です。

- 'New Key' を選択します
- キーに名前を付けます
- アクセスを許可するドメインを選択します
- 'Create' をクリックします
認証
リクエストを認証するには、リクエストのx-api-keyヘッダーにAPIキーを含める必要があります。
リクエストの例:
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はトラフィック全体ではなく、エージェントのトラフィックに占める割合です。
レスポンスの例
{
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つの行の間で値が下がったところが、訪問者が読むのをやめた位置です。
// 「ページの半分を超えて読んだ割合は?」
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回程度に抑えてください。データは日単位で集計されるため、それより頻繁にポーリングしても新しい情報は得られません。より高い頻度が必要な場合は、お問い合わせください。
