00 — CoverPrivate · Invitation only · sheet.zaber.tech

Publish a sheettab as an API.

Sheet Zaber turns one tab of one Google spreadsheet into one HTTP endpoint: list, read one, search, take an A1 range, append, merge, replace, delete — over a Bearer key, with your own Google grant doing the read and the write. Row numbers are never handed back to you, and every limit is printed in the docs before you meet it.

If it is not documented at /docs, this page does not promise it.

There is no open signup — an account is created only when an invitation code the owner issued is redeemed.Scroll — 01 The idea ↘
01 — The idea

A spreadsheet, with an address

One tab becomes one endpoint, and rows are addressed by key, never by number.
02 — Documented defaults

Four numbers, all from the contract

These are the platform's stated defaults — 1000 requests an hour and 10000 a day per key, a 1 MB request body, and 90 days of request-log retention. They are not statistics about traffic here.

Per key, per hour
1000
override per API by the hour
Per key, per day
10000
a 429 carries Retry-After
Request body
1 MB
larger POST → 413
Log retention
90 days
owner-configurable
03 — How a request travels

One key, four checks,one envelope

the endpoint
GET{api}GET{api}/{pk}GET{api}/searchGET{api}/range/{A1}POST{api}PATCH{api}/{pk}DELETE{api}/{pk}

GET /{api} · read scope · 200 · data [ ]

List records: column=value filters, sort, limit/offset paging and a fields subset, all applied to the tab server-side. No limit means every row of the tab.

filled dot = write scope · click, Enter or arrow-key a verb

The verb set, one envelope

List, read one by key, case-insensitive substring search, a raw A1 range, then append, merge, replace and delete — all answered with { data, meta } or the single { error } shape, over Authorization: Bearer, never a query-string key.

Rows have keys, not numbers

PATCH, PUT and DELETE address a row through the primary-key column you designate per API, resolved at request time. No row number is stored, and an API without a key is read-and-append only.

every requestkeyaccesslimitsrowchecking · key

Four checks before Google

Key-hash lookup, ownership and scope, the hour and day counters, then primary-key resolution. Fail one and your sheet is never read, the refusal comes back in the same error envelope, and the request is still logged.

rate limits
day window 10,000min 60 · 1,000 counted

A steady 1,000 an hour reaches the 10,000-a-day window in 10 of 24 hours. That is the documented default, not a customer's traffic.

Limits you can plan around

1000 requests an hour and 10000 a day per key by default, with a per-API hourly override on top. A 429 carries Retry-After and the same error envelope as every other refusal.

  • Invitation only

    ZABER-XXXX-XXXX codes, stored as SHA-256 hashes, with a use limit, an expiry and revocation.

  • Sign-in

    Google authorization-code flow with PKCE; identity comes from an ID token verified server-side, anchored on its sub claim.

  • Sessions

    HMAC-SHA-256 signed httpOnly cookie (__Host- prefixed and Secure in production), re-checked against the users row on every guarded request.

  • Tokens at rest

    Google refresh tokens sealed with AES-256-GCM, so a leaked database is not a usable credential.

  • API keys

    sz_live_ plus 32 hex characters, kept only as a hash, shown once when you create them.

  • Log retention

    90 days by default, owner-configurable. No headers, no bodies, no keys and no cell contents in any log.

  • Google data

    Used only to publish the tabs you register. Not sold, not shared with another app, not used for advertising — and cell contents are never copied into this database.

04 — Example request shape

What a call looks like

The same snippets the playground and the docs use.

GET one API, first 25 rows

Placeholders, not credentials: <api-id> and sz_live_… stand for your own values.

cURL
curl 'https://sheet.zaber.tech/api/v1/<api-id>?limit=25' \
  -H "Authorization: Bearer sz_live_…"
Success envelope
{
  "data": [ { "<header cell>": "<cell value>" } ],
  "meta": {
    "api_id":     "<api-id>",
    "count":      <rows returned>,
    "limit":      25,
    "offset":     0,
    "duration_ms": <server milliseconds>
  }
}
Every non-2xx
{
  "error": {
    "code":     "<error code, e.g. rate_limited>",
    "message":  "<what failed>",
    "category": "auth | rate_limit | validation | google | not_found | internal"
  }
}

The two plates above are the documented response shapes — field names from the contract, values left as angle brackets on purpose. They are not a working credential and not a live response.

A real key is sz_live_ plus 32 hex characters, is shown once when you create it, is stored only as its SHA-256 hash, and must travel in the Authorization header: query-string auth is refused because it leaks into logs and referrers.

05 — Access

How you get in

Four steps, and none of them are a signup form.

  1. 01

    Receive an invitation code

    The platform owner issues ZABER-XXXX-XXXX codes. Only the SHA-256 hash is stored, and a code carries a use limit, an optional expiry and revocation.
  2. 02

    Sign in with Google

    Authorization-code flow with PKCE, and the ID token is verified server-side before anything is trusted: identity is anchored on the verified sub, never on a typed email . The consent request asks for openid email profile plus the Sheets read/write scope and drive.file, which covers only files you choose in Google's Picker.
  3. 03

    Redeem the code

    Redemption is one atomic conditional UPDATE inside the registration transaction, so two people racing on a single-use code produce exactly one account . Your row is created with role = 'user'; only the configured owner email can ever be owner.
  4. 04

    Register a spreadsheet

    You paste a sheet URL or id, and the backend proves the grant by calling spreadsheets.get with your own connection: a spreadsheet only someone else can read is never created .

One more rule worth knowing: disable a user and their session stops working on the next request, because the cookie is only a signature — the users row is the authority.

06 — Stores

Stores using it

  • Corso Velle

    Clothing store

  • ARZ

    Panjabi and traditional wear

07 — Questions

Asked, and answered

Can I use a Google Sheet as a REST API?

Yes. Sheet Zaber publishes one tab of one Google spreadsheet as one HTTP endpoint that can list, read one record, search, take an A1 range, append, merge, replace and delete.

How are requests authenticated?

With an API key in the Authorization: Bearer header. Keys are shown once when created and stored only as a SHA-256 hash. Query-string keys are refused.

What are the rate limits?

By default 1000 requests an hour and 10000 a day per key, with a per-API hourly override. Past a window comes a 429 with Retry-After.

Does Sheet Zaber copy my spreadsheet data?

No. Your own Google grant does the read and the write, and cell contents are never copied into its database or written to its logs.

Can anyone sign up?

No. The platform is private: an account is created only when an invitation code issued by the owner is redeemed after signing in with Google.

08 — Where to read further

The contract is the product.

One published contract is the source of truth for every verb, error code and default on this page; the docs site renders its examples from the same builders as the playground. The platform is private, and its request logs are nobody's marketing material.