---
title: "Fetch your first hosted analytics rows"
description: "Query an authorized Site with a server-held API key."
canonical_url: "https://gscdump.com/gscdump-sdk/guides/start/hosted-first-result"
last_updated: "2026-10-03T07:15:32.063Z"
---

# Fetch your first hosted analytics rows

This request returns rows from an authorized Site. It runs on your server, where the API key stays private.

## Before you start

### Create a user API key

Generate a user API key in [Agent setup](/app/developers#api-keys). Copy it when shown and store it in `GSCDUMP_API_KEY`. User keys have a fixed scope set. [Keys and scopes](/gscdump-sdk/guides/operate/keys-and-scopes) explains access checks.

### Find a Site ID

In the app, select your Site. Open **Settings → Site information** and copy **Site ID**. Set it in `GSCDUMP_SITE_ID`.

The public ID starts with `s_`. A Google `sc-domain:` or URL-prefix identifier is a different value. `s_01` in contract examples is a placeholder.

## Make the request

Install with `pnpm add @gscdump/sdk`. Run this on your server:

::pre{tabindex="0"}
```ts
import { createGscdumpV1Client } from '@gscdump/sdk/v1'

const apiKey = process.env.GSCDUMP_API_KEY
const siteId = process.env.GSCDUMP_SITE_ID
if (!apiKey || !siteId)
  throw new Error('Set GSCDUMP_API_KEY and GSCDUMP_SITE_ID')

const client = createGscdumpV1Client({ credential: () => apiKey })
const result = await client.queryAnalyticsRows({
  params: { siteId },
  body: { dimensions: ['query'], metrics: ['clicks', 'impressions'], rowLimit: 100 },
})

console.log(result.data.rows)
console.log(result.meta.requestId)
```
::

The [hosted HTTP contract](/gscdump-sdk/api/hosted-http) defines this request. The code logs returned data and does not assume any query exists.

<docsexample title="Hosted row result" input="queryAnalyticsRows: query dimension; clicks and impressions metrics; 100 row limit" result="The contract returns data.rows as an array and meta.requestId as a string. An empty array is valid." failure="If access fails, check analytics:execute and authorization for the exact Site ID." caption="Source: analytics.rows.query v1 contract; Site and date window: your request; result: contract fields, not a recorded Site response."></docsexample>

## Read the rows and metadata

::table{tabindex="0"}
| Field                                                | Meaning                                       |
| ---------------------------------------------------- | --------------------------------------------- |
| `data.rows`                                          | Matching rows. An empty array is valid.       |
| `meta.requestId`                                     | Identifier to include with a support request. |
| `meta.sourceName`, `meta.sourceKind`, `meta.queryMs` | Query source and execution details.           |
::

Rows do not include Report totals or sync metadata. Use [hosted analytics](/gscdump-sdk/guides/read-data/hosted-analytics) when you need those.

## If access fails

Check the API key, Site ID, `analytics:execute` scope, and Site authorization. Catch typed errors with [Errors and retry](/gscdump-sdk/guides/operate/errors-and-retry). If rows are empty, confirm synced dates before widening the query.

## Build on the result

Add a server route with [Nuxt](/gscdump-sdk/guides/build-integrations/nuxt), [Next.js](/gscdump-sdk/guides/build-integrations/nextjs), or [Hono / Express](/gscdump-sdk/guides/build-integrations/hono-express).

## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
