Field Projection
Select a subset of columns to return using the fields query parameter, reducing payload size.
Field projection lets you tell the SheetsAPI which columns to include in the response. Instead of receiving every column in a sheet, you declare exactly the fields you need and the API omits the rest from each row object. This shrinks response payloads, speeds up serialisation on the server, and reduces the amount of data your client has to parse - especially useful for wide sheets with many columns that your current view does not need.
GET https://api.gkit.io/api/spreadsheets/{userKey}/{sheetName}?fields=name,email
Authorization: Bearer sk_...
Syntax
Append fields as a comma-separated list of column names:
?fields=col1,col2,col3
- Column names are case-sensitive and must match the header row of the sheet exactly.
Emailandemailare treated as different columns. - Whitespace around commas is trimmed, so
fields=name, emailandfields=name,emailare equivalent. - The parameter can be combined freely with
search,sort,limit, andoffset.
With fields vs without fields
The example below uses a users sheet with six columns. Projecting to two reduces each
row object from six keys to two.
Without fields | With ?fields=name,email | |
|---|---|---|
| Columns returned | id, name, email, role, created_at, status | name, email |
| Row object | { id, name, email, role, created_at, status } | { name, email } |
| Payload per row | ~160 bytes | ~50 bytes |
meta envelope | always present | always present |
The meta object (total, limit, offset) is returned regardless of which fields are
projected.
Code examples
Select only name and email
curl "https://api.gkit.io/api/spreadsheets/uk_abc123/users?fields=name%2Cemail" \
-H "Authorization: Bearer sk_..."Response:
{
"data": [
{ "name": "Alice", "email": "alice@x.com" },
{ "name": "Bob", "email": "bob@x.com" }
],
"meta": { "total": 2, "limit": 20, "offset": 0 }
}Combine with search and limit
Fetch the first 10 active users, returning only their name and email:
curl "https://api.gkit.io/api/spreadsheets/uk_abc123/users\
?fields=name%2Cemail\
&search=status%3Aactive\
&limit=10" \
-H "Authorization: Bearer sk_..."Filters and pagination apply before projection - meta.total reflects the filtered count,
not the unprojected full row count.
TypeScript example
Use Pick to keep your response type aligned with the fields you project:
interface UserRow {
id: string;
name: string;
email: string;
role: string;
created_at: string;
status: string;
}
type ProjectedUser = Pick<UserRow, "name" | "email">;
interface SheetsResponse<T> {
data: T[];
meta: { total: number; limit: number; offset: number };
}
const params = new URLSearchParams({ fields: "name,email", limit: "10" });
const res = await fetch(`https://api.gkit.io/api/spreadsheets/${userKey}/users?${params}`, {
headers: { Authorization: `Bearer ${apiKey}` },
});
const { data, meta }: SheetsResponse<ProjectedUser> = await res.json();
// data[0].name ✓
// data[0].email ✓
// data[0].role - TypeScript error: property does not exist on ProjectedUserThe Pick utility type narrows the inferred row shape to exactly the projected columns,
catching accidental access to excluded fields at compile time.
Notes
- Non-existent fields are silently ignored. If you request
?fields=name,typo_columnandtypo_columndoes not exist in the sheet, the API returns rows with onlyname- no error is raised. - Zero valid fields returns all columns. If every name in the
fieldslist is unrecognised, the API falls back to returning the full row object as iffieldswere not specified. metais always present. Projecting fields never suppresses themetaenvelope;total,limit, andoffsetare always included in the response.- URL encoding. A literal comma must be percent-encoded as
%2Cin raw URLs. HTTP client libraries (fetch withURLSearchParams, axios, curl with--data-urlencode) handle this automatically when you build URLs through their parameter API.
See Query Parameters for the complete list of supported parameters, and Filtering for combining field projection with row-level search operators.