Usage and Cost Analytics API
Kueri penggunaan token dan biaya untuk organisasi Claude Console atau Claude Enterprise Anda berdasarkan model, workspace, kunci API, aktor, dan lainnya.
Usage and Cost Analytics API melaporkan riwayat penggunaan token dan biaya untuk organisasi Anda, yang dirinci berdasarkan dimensi yang Anda pilih, seperti model, workspace, kunci API, atau pengguna atau akun layanan di balik setiap permintaan. Untuk organisasi Claude Console, data ini serupa dengan yang ditampilkan oleh halaman Usage dan Cost di Claude Console.
API ini memiliki dua endpoint:
GET /v1/organizations/analytics/usagemelaporkan jumlah token dan jumlah permintaan.GET /v1/organizations/analytics/costmelaporkan biaya dalam USD.
Usage and Cost Analytics API masih dalam tahap beta. Kirim header anthropic-beta: analytics-usage-cost-2026-08-24 dan header anthropic-version pada setiap permintaan. SDK dan CLI ant mengirimkan kedua header tersebut untuk Anda dan mengambil halaman-halaman berikutnya saat Anda membaca hasilnya, sehingga limit hanya menetapkan ukuran halaman.
Gunakan API ini untuk:
- Mengatribusikan pengeluaran: Merinci biaya dan penggunaan token berdasarkan workspace, kunci API, model, tingkat layanan, atau identitas yang membuat setiap permintaan.
- Menemukan konsumen teratas: Mengurutkan hasil berdasarkan token, permintaan, atau biaya untuk menjawab pertanyaan seperti “kunci API mana yang paling banyak mengeluarkan biaya bulan ini?”
- Membangun deret waktu: Membagi hasil ke dalam bucket harian, per jam, atau per menit untuk dasbor dan laporan keuangan.
- Mengintegrasikan sekali saja: Endpoint, parameter, dan field respons yang sama melayani organisasi Claude Console dan Claude Enterprise.
Mulai cepat
Dapatkan penggunaan token harian untuk minggu pertama bulan September, satu baris untuk setiap model dan hari:
client = anthropic.Anthropic()
rows = client.beta.organization.analytics.usage.list(
starting_at="2026-09-01T00:00:00Z",
ending_at="2026-09-08T00:00:00Z",
time_bucket_width="1d",
group_by=["model"],
limit=10,
)
for row in rows:
print(f"{row.starting_at} {row.group.model}: {row.usage.total_tokens}")Respons berisi satu baris untuk setiap model dan hari yang memiliki penggunaan, dengan total_tokens terbesar terlebih dahulu. Contoh ini menampilkan satu baris:
{
"data": [
{
"starting_at": "2026-09-03T00:00:00Z",
"ending_at": "2026-09-04T00:00:00Z",
"group": {
"product": null,
"model": "claude-sonnet-5",
"context_window": null,
"inference_geo": null,
"speed": null,
"slack_channel_id": null,
"claude_tag_category": null,
"claude_tag_user_id": null,
"rbac_group_id": null,
"workspace_id": null,
"service_tier": null,
"user_profile_id": null,
"agent_id": null,
"environment_id": null,
"deployment_id": null,
"session_id": null,
"actor": null,
"actor_type": null,
"api_key_id": null
},
"usage": {
"uncached_input_tokens": 1284500,
"cache_creation": {
"ephemeral_1h_input_tokens": 0,
"ephemeral_5m_input_tokens": 215300
},
"cache_read_input_tokens": 3200000,
"output_tokens": 891000,
"total_tokens": 5590800,
"server_tool_use": {
"web_search_requests": 12
},
"requests": 4210
}
}
],
"has_more": true,
"next_page": "page_V2mQ4dkt9HcbX3pLr...",
"data_refreshed_at": "2026-09-18T16:02:11Z"
}Bagaimana hasil dibentuk
- Setiap baris memiliki tiga bagian:
starting_atdanending_atmemberikan periode yang dicakup baris tersebut,groupmenampung setiap dimensi, danusage(ataucostpada endpoint biaya) menampung metrik. - Dimensi bernilai null kecuali dikelompokkan: Sebuah dimensi di
groupbernilainullkecuali Anda mencantumkannya digroup_by[]. Dimensi yang dikelompokkan juga bernilainullpada baris yang tidak memiliki nilai untuknya, sepertimodelpada penggunaan eksekusi kode.group_by[]menerima hingga lima dimensi. - Satu baris untuk setiap kombinasi: Setiap baris adalah satu kombinasi dari dimensi yang dikelompokkan, dan setiap kombinasi yang memiliki penggunaan atau biaya muncul tepat satu kali di seluruh halaman sebuah kueri. Tanpa
group_by[]dan tanpatime_bucket_width, respons berupa satu baris yang menjumlahkan seluruh rentang. - Time bucket bersifat opsional: Atur
time_bucket_widthke1m,1h, atau1duntuk membagi setiap kombinasi berdasarkan bucket UTC;starting_atdanending_atsetiap baris kemudian menjadi batas bucket-nya. Bucket tanpa penggunaan atau biaya tidak menghasilkan baris. - Diurutkan berdasarkan peringkat secara default: Baris diurutkan berdasarkan metrik
order_bydi seluruh rentang, dari yang terbesar terlebih dahulu secara default (order=ascmembalikkannya). Untuk membangun deret waktu, aturtime_bucket_widthdanorder_by=time. Baris kemudian dikembalikan satu time bucket demi satu time bucket, dengan bucket terbaru terlebih dahulu secara default (order=ascmenempatkan yang terlama terlebih dahulu), dan baris terbesar terlebih dahulu di dalam setiap bucket. Isi bucket yang kosong dengan nol. - Filter bekerja bersama pengelompokan: Sebagian besar dimensi yang dapat Anda kelompokkan memiliki filter daftar yang sesuai dalam notasi kurung siku, seperti
models[]=claude-opus-5-5. Ulangi parameter untuk meneruskan beberapa nilai, hingga 100. Beberapa nilai untuk filter yang sama digabungkan dengan OR, dan filter yang berbeda digabungkan dengan AND. Filter dangroup_by[]bersifat independen; Anda dapat memfilter berdasarkan dimensi apa pun dengan atau tanpa mengelompokkannya, atau sebaliknya.
Dimensi seperti model dan actor berlaku untuk setiap organisasi. Beberapa, seperti api_key_id, hanya berlaku untuk organisasi Claude Console, dan yang lainnya, seperti slack_channel_id, hanya berlaku untuk organisasi Claude Enterprise. Dimensi yang tidak berlaku untuk organisasi Anda bernilai null di setiap baris dan filternya tidak cocok dengan apa pun; pengecualiannya adalah rbac_group_id, yang justru mengembalikan error ketika tim tidak tersedia untuk organisasi Anda. Referensi API penggunaan dan biaya mencantumkan setiap dimensi, filter, dan nilai.
Aktor
Dimensi actor menunjukkan kepada siapa sebuah permintaan diatribusikan: pengguna, akun layanan, identitas cloud terfederasi (principal AWS atau Google Cloud, untuk organisasi yang mengakses Claude melalui platform cloud mereka), atau, ketika tidak ada satu pun dari itu di balik permintaan, kunci API itu sendiri. Saat Anda mengelompokkan berdasarkan actor, actor pada setiap baris adalah objek yang type-nya menyatakan jenisnya. Penggunaan yang tidak dapat diatribusikan ke identitas mana pun memiliki actor: null.
Kunci pribadi dan kunci akun layanan bertindak sebagai pengguna atau akun layanan yang ditautkan dengannya, sehingga permintaannya menampilkan identitas tersebut sebagai actor dan kuncinya di api_key_id. Kunci workspace lama tidak ditautkan ke identitas, sehingga kunci tersebut muncul sebagai actor sekaligus api_key_id. Pengecualiannya adalah kunci yang dibuat Claude Code ketika seorang anggota masuk dengan akun Claude Console mereka: kunci tersebut berada di workspace Claude Code, dan penggunaannya diatribusikan ke anggota tersebut. Permintaan yang dibuat tanpa kunci API, seperti dari Claude Console atau dengan token Workload Identity Federation, memiliki api_key_id: null; actor dari workload terfederasi adalah akun layanannya. Untuk menyertakan penggunaan tanpa kunci API dalam filter api_key_ids[], tambahkan entri kosong: api_key_ids[]=.
Filter api_key_ids[] dan actor_ids[] menjawab pertanyaan yang berbeda. api_key_ids[]=apikey_... mencocokkan setiap permintaan yang diautentikasi oleh kunci tersebut, kepada siapa pun permintaan itu diatribusikan. actor_ids[]=apikey_... hanya mencocokkan permintaan yang diatribusikan ke kunci itu sendiri.
Endpoint penggunaan
GET /v1/organizations/analytics/usage mengembalikan jumlah token berdasarkan tipe. order_by menerima total_tokens (default), output_tokens, uncached_input_tokens, requests, atau time.
Misalnya, untuk melihat penggunaan selama seminggu untuk satu workspace dan satu kunci API, dirinci berdasarkan tingkat layanan (satu baris untuk setiap tingkat, mencakup seluruh minggu):
client = anthropic.Anthropic()
rows = client.beta.organization.analytics.usage.list(
starting_at="2026-09-01T00:00:00Z",
ending_at="2026-09-08T00:00:00Z",
workspace_ids=["wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"],
api_key_ids=["apikey_01Rj2N8SVvo6BePZj99NhmiT"],
group_by=["service_tier"],
)
for row in rows:
print(f"{row.group.service_tier}: {row.usage.total_tokens}")Untuk mencari ID kunci API dan workspace, gunakan endpoint List API Keys dan List Workspaces atau Claude Console.
Untuk menemukan pengguna, akun layanan, dan kunci API mana yang membuat permintaan terbanyak dalam sebulan:
client = anthropic.Anthropic()
rows = client.beta.organization.analytics.usage.list(
starting_at="2026-09-01T00:00:00Z",
ending_at="2026-10-01T00:00:00Z",
group_by=["actor"],
order_by="requests",
limit=25,
)
for row in rows:
print(f"{row.group.actor}: {row.usage.requests}")Endpoint biaya
GET /v1/organizations/analytics/cost menerima filter, dimensi, dan time bucket yang sama dengan endpoint /usage. Objek cost pada setiap baris memuat amount (biaya setelah diskon dan sebelum kredit apa pun diterapkan), list_amount (biaya berdasarkan harga daftar), currency (selalu "USD"), dan requests. Jumlah berupa string desimal dalam sen dengan enam angka desimal: "41280.000000" adalah $412,80 USD. order_by menerima amount (default), list_amount, atau time.
Dua dimensi tambahan hanya ada pada endpoint ini dan tidak dihitung dalam batas lima dimensi: group_by[]=cost_type membagi setiap baris menjadi satu baris untuk setiap jenis biaya, dan group_by[]=token_type membagi biaya token menjadi satu baris untuk setiap jenis token. limit juga tidak berlaku untuk kedua dimensi ini, sehingga satu halaman dapat berisi lebih dari limit baris. Misalnya, biaya berdasarkan model, jenis biaya, dan jenis token selama satu bulan:
client = anthropic.Anthropic()
rows = client.beta.organization.analytics.cost.list(
starting_at="2026-09-01T00:00:00Z",
ending_at="2026-10-01T00:00:00Z",
group_by=["model", "cost_type", "token_type"],
)
for row in rows:
print(
f"{row.group.model} {row.group.cost_type} {row.group.token_type}: {row.cost.amount}"
)Untuk setiap model, respons berisi lima baris tokens (satu untuk setiap jenis token) ditambah masing-masing satu baris untuk web_search, code_execution, dan session_usage. Salah satu baris tersebut:
{
"starting_at": "2026-09-01T00:00:00Z",
"ending_at": "2026-10-01T00:00:00Z",
"group": {
"model": "claude-opus-5",
...,
"cost_type": "tokens",
"token_type": "cache_read_input_tokens"
},
"cost": {
"currency": "USD",
"amount": "41280.000000",
"list_amount": "51600.000000",
"requests": null
}
}Objek group memuat setiap dimensi dan disingkat di sini. Dengan group_by[]=cost_type atau token_type ditentukan, requests bernilai null di setiap baris.
Rentang tanggal dan time bucket
- Timestamp menggunakan format RFC 3339 dengan offset UTC, misalnya
2026-09-01T00:00:00Z.starting_atbersifat inklusif danending_atbersifat eksklusif. starting_atharus pada atau setelah 1 Januari 2026, dan dalam 365 hari terakhir. Satu permintaan dapat mencakup paling lama 31 hari;ending_atsecara default adalah 31 hari setelahstarting_atatau waktu saat ini, mana yang lebih awal.ending_atwajib diisi setiap kalitime_bucket_widthdiatur, dan dengantime_bucket_width=1msatu permintaan dapat mencakup paling lama 24 jam.- Kedua ujung rentang dibulatkan ke bawah ke batas bucket UTC, atau ke jam ketika
time_bucket_widthtidak diatur. Misalnya, dengantime_bucket_width=1h,starting_atbernilai2026-09-01T10:43:00Zdiperlakukan sebagai2026-09-01T10:00:00Zdanending_atbernilai2026-09-01T15:43:00Zsebagai2026-09-01T15:00:00Z, sehingga respons mencakup pukul 10:00 hingga 15:00 UTC.
Kesegaran data
Setiap respons menyertakan timestamp data_refreshed_at, dan penggunaan setelah waktu tersebut hilang atau parsial. Ketika belum ada data yang tersedia untuk bagian mana pun dari rentang yang diminta, data_refreshed_at bernilai null dan data kosong. Data biasanya diperbarui dalam 4 jam setelah penggunaan yang mendasarinya dan dapat memakan waktu hingga 24 jam. Nilai dapat direvisi saat peristiwa yang terlambat tiba dan rekonsiliasi berjalan, hingga sekitar 7 hari setelah akhir bulan kalender. Misalnya, nilai untuk 1 Oktober dapat berubah hingga sekitar 7 November. Untuk hasil yang stabil di seluruh panggilan berulang, atur ending_at pada atau sebelum data_refreshed_at yang sudah Anda lihat; untuk total final, kueri hanya bulan-bulan yang berakhir setidaknya 7 hari yang lalu. Setiap halaman dari kueri berpaginasi membaca snapshot data yang sama, sehingga data_refreshed_at identik di seluruh halaman.
Migrasi dari Usage and Cost API
Bagian ini ditujukan untuk organisasi Claude Console yang memanggil Usage and Cost API lama (/v1/organizations/usage_report/messages dan /v1/organizations/cost_report). Kunci Admin API Anda, header anthropic-version, starting_at dan ending_at, nilai lebar bucket (1m, 1h, 1d), notasi kurung siku, nama field paginasi, serta nama field token dan biaya tetap berlaku. Yang berubah:
| Usage and Cost API | Usage and Cost Analytics API |
|---|---|
| Tanpa header beta | anthropic-beta: analytics-usage-cost-2026-08-24 pada setiap permintaan |
| Data biasanya muncul dalam 5 menit | Data biasanya diperbarui dalam 4 jam dan dapat memakan waktu hingga 24 jam (lihat Kesegaran data) |
data adalah daftar time bucket, yang terlama terlebih dahulu, termasuk yang kosong, masing-masing dengan daftar results yang entrinya menampung dimensi dan metrik berdampingan | data adalah daftar baris yang diurutkan berdasarkan order_by, masing-masing dengan starting_at dan ending_at sendiri, dimensi di group, dan metrik di usage atau cost. Kombinasi tanpa penggunaan atau biaya tidak memiliki baris. |
bucket_width, default 1d | time_bucket_width, tanpa default. Teruskan time_bucket_width=1d untuk mempertahankan baris harian; hilangkan untuk total seluruh rentang. Endpoint biaya juga menerima setiap filter serta bucket 1m dan 1h. |
limit menghitung time bucket per halaman | limit menghitung baris per halaman (1 hingga 1.000, default 20), sehingga jumlah halaman bergantung pada berapa banyak kombinasi yang memiliki data |
| Rentang tanggal apa pun, dipaginasi maju per bucket | starting_at pada atau setelah 1 Januari 2026, dan dalam 365 hari terakhir, paling banyak 31 hari per permintaan, ending_at wajib dengan time_bucket_width, dan paling banyak 24 jam dengan bucket 1m (lihat Rentang tanggal dan time bucket). Bagi rentang yang lebih panjang menjadi beberapa permintaan. |
account_ids[], service_account_ids[], group_by[]=account_id, group_by[]=service_account_id | actor_ids[] dengan ID bertag yang sama, dan group_by[]=actor atau actor_type; baca actor.user_id atau actor.service_account_id. Lihat Aktor. |
context_window[] | context_windows[] |
group_by[]=description pada laporan biaya, dengan string description | Tidak ada description. Sebagai gantinya, kelompokkan berdasarkan dimensi terstruktur: salah satu dari model, cost_type, token_type, context_window, service_tier, inference_geo, dan speed, yang semuanya muat dalam satu permintaan. |
| Kunci API atau ID workspace yang tidak dikenal mengembalikan error | Tidak cocok dengan apa pun, termasuk nama models[] yang salah eja. Setiap daftar menerima hingga 100 nilai. |
workspace_id: null untuk workspace default | workspace_id asli dari workspace default (lihat Bagaimana workspace default direpresentasikan?) |
inference_geo: "not_available" dan service_tier: "standard" pada penggunaan tanpa geo atau tingkat | null untuk keduanya. inference_geos[]=not_available tetap mencocokkan baris tanpa inference geo. |
service_tier biaya adalah standard atau batch; amount seperti "123.45" | Tingkat yang sebenarnya; amount dengan enam angka desimal, seperti "123.450000", ditambah list_amount. |
| Eksekusi kode tidak ada dalam laporan penggunaan; tidak ada jumlah permintaan | Eksekusi kode muncul sebagai baris penggunaan dengan model: null; menambahkan requests pada kedua endpoint dan total_tokens pada baris penggunaan |
Untuk mereproduksi laporan harian lama, minta time_bucket_width=1d dengan group_by[] yang sama, telusuri halaman dengan limit=1000, lalu kelompokkan baris berdasarkan starting_at dan isi hari yang hilang dengan nol. Tambahkan order_by=time&order=asc untuk mendapatkan hari-hari secara berurutan. Penggunaan harian berdasarkan model selama 1 minggu, sebelumnya:
curl --globoff "https://api.anthropic.com/v1/organizations/usage_report/messages?\
starting_at=2026-09-01T00:00:00Z&\
ending_at=2026-09-08T00:00:00Z&\
group_by[]=model&\
bucket_width=1d" \
-H "anthropic-version: 2023-06-01" \
-H "x-api-key: $ANTHROPIC_API_KEY"dan sesudahnya:
client = anthropic.Anthropic()
rows = client.beta.organization.analytics.usage.list(
starting_at="2026-09-01T00:00:00Z",
ending_at="2026-09-08T00:00:00Z",
time_bucket_width="1d",
group_by=["model"],
limit=1000,
)
for row in rows:
print(f"{row.starting_at} {row.group.model}: {row.usage.total_tokens}")Biaya harian berdasarkan workspace, model, tingkat layanan, jendela konteks, dan inference geo, dibagi berdasarkan jenis biaya dan jenis token:
client = anthropic.Anthropic()
rows = client.beta.organization.analytics.cost.list(
starting_at="2026-09-01T00:00:00Z",
ending_at="2026-09-08T00:00:00Z",
time_bucket_width="1d",
group_by=[
"workspace_id",
"model",
"service_tier",
"context_window",
"inference_geo",
"cost_type",
"token_type",
],
limit=1000,
)
for row in rows:
group = row.group
print(
f"{row.starting_at} {group.workspace_id} {group.model} {group.service_tier} "
f"{group.context_window} {group.inference_geo} {group.cost_type} {group.token_type}: "
f"{row.cost.amount}"
)Migrasi dari laporan penggunaan dan biaya Claude Enterprise
Bagian ini ditujukan untuk organisasi Claude Enterprise yang memanggil endpoint laporan Claude Enterprise Analytics API usage_report, cost_report, user_usage_report, dan user_cost_report di bawah /v1/organizations/analytics/. Endpoint tersebut merupakan endpoint lama dan tetap didukung. Beralihlah ke /analytics/usage dan /analytics/cost ketika Anda menginginkan salah satu dari hal berikut:
- Setiap grup di setiap time bucket, alih-alih 100 grup teratas di setiap bucket
- Pengelompokan berdasarkan
actoratauactor_typebersama dengan dimensi lain, pada penggunaan maupun biaya - Baris yang diurutkan berdasarkan metrik pilihan Anda di seluruh rentang, atau diurutkan berdasarkan time bucket
- Satu integrasi yang juga melayani organisasi Claude Console
Kunci Anda, tanggal paling awal, jangkauan mundur 365 hari dan rentang 31 hari, nama dan nilai filter serta dimensi (kecuali user_ids[] dan nilai produk Claude Tag), field actor pengguna, field metrik dan jumlah, data_refreshed_at, aturan cursor, dan batas laju tingkat organisasi tetap berlaku. Satu-satunya header baru adalah header beta analytics-usage-cost-2026-08-24. Yang berubah:
| Laporan Claude Enterprise | Usage and Cost Analytics API |
|---|---|
usage_report dan cost_report mengembalikan time bucket, yang terlama terlebih dahulu, termasuk yang kosong, masing-masing menampung paling banyak 100 grup teratasnya; bucket_width default ke 1d dan limit menghitung bucket | Baris yang mencakup setiap kombinasi yang memiliki data, diurutkan berdasarkan order_by, masing-masing dengan starting_at dan ending_at sendiri, dimensi di group, dan metrik di usage atau cost. time_bucket_width bersifat opsional dan limit menghitung baris. |
Parameter time bucket adalah bucket_width | Parameternya adalah time_bucket_width, dengan nilai yang sama |
Pada usage_report dan cost_report, ending_at bersifat opsional dengan bucket_width dan bucket 1m dapat mencakup hingga 31 hari | ending_at wajib dengan time_bucket_width; bucket 1m mencakup paling banyak 24 jam per permintaan |
user_usage_report dan user_cost_report mengembalikan satu baris per pengguna | group_by[]=actor&actor_types[]=user_actor. Tanpa filter tersebut, Anda juga mendapatkan baris untuk identitas non-pengguna dan baris actor: null untuk penggunaan yang tidak teratribusi. |
Penggunaan Claude Tag memiliki product: "claude-tag" | product: "claude_tag"; products[] menerima kedua ejaan |
Nama models[] yang tidak dikenali mengembalikan error 400 | Tidak cocok dengan apa pun |
user_ids[] | actor_ids[] dengan ID bertag user_... yang sama |
exclude_deleted_users pada laporan per pengguna | Memerlukan group_by[]=actor; tanpanya, permintaan mengembalikan error 400. Parameter ini hanya menghapus baris yang actor-nya adalah pengguna dengan deleted: true; baris untuk identitas lain dan baris dengan actor: null tetap ada. |
Biaya per pengguna selama sebulan, sebelumnya:
client = anthropic.Anthropic()
rows = client.beta.organization.analytics.user_cost_report.list(
starting_at="2026-09-01T00:00:00Z",
ending_at="2026-10-01T00:00:00Z",
limit=100,
)
for row in rows:
print(f"{row.actor.user_id}: {row.amount}")dan sesudahnya, dengan tambahan rincian berdasarkan produk:
client = anthropic.Anthropic()
rows = client.beta.organization.analytics.cost.list(
starting_at="2026-09-01T00:00:00Z",
ending_at="2026-10-01T00:00:00Z",
actor_types=["user_actor"],
group_by=["actor", "product"],
limit=100,
)
for row in rows:
actor = row.group.actor
if actor is not None and actor.type == "user_actor":
print(f"{actor.user_id} {row.group.product}: {row.cost.amount}")Pertanyaan yang sering diajukan
Bagaimana workspace default direpresentasikan?
Workspace default dari organisasi Claude Console memiliki ID wrkspc_ sendiri, seperti workspace lainnya. Baris untuk workspace default memiliki ID tersebut di workspace_id, dan Anda dapat memfilternya dengan workspace_ids[]. List Workspaces tidak menyertakan workspace default kecuali Anda meneruskan include_default=true. Untuk memeriksa apakah workspace_id yang tidak dikenal adalah workspace default, teruskan ID tersebut ke Get Workspace: workspace default mengembalikan "name": "Default".
Bagaimana cara mendapatkan biaya per pengguna untuk Claude Code?
Panggil endpoint biaya dengan products[]=claude_code&group_by[]=actor. Organisasi Claude Console juga dapat menggunakan Claude Code Analytics API, yang melaporkan aktivitas Claude Code per pengguna dan estimasi biaya.
Lihat juga
- Usage and Cost API (lama)
- Analytics API: API analitik dan jenis kunci mana yang dibutuhkan organisasi Anda
- Claude Code Analytics API
- Referensi Admin API
- Harga
Was this page helpful?