Getting started

Add a data source, wire it to an output, and ship a live API endpoint in about a minute.

The 60-second walkthrough

Each step in the editor is a node. Sources fetch and store data; transforms shape it; the output node turns the result into a deployed REST endpoint. Connect them with edges, hit Deploy, and you have a URL.

1. Sign up

Create an account at /register. We send a verification email; click the link and you land on your first workspace. No credit card required for the free tier.

2. Add a source

In the editor, drag a Source node onto the grid. v1 supports two connector types:

  • Google Sheets — paste a spreadsheet URL or ID. Public or service-account auth.
  • REST API — paste an endpoint URL. Bearer / API-key auth, optional pagination.

Click Test connection, then Detect schema. The sync runs immediately so your data is queryable seconds later.

3. Shape the data (optional)

Drop a Filter, Transform, or Aggregate node between the source and the output. Configs are validated at save time — a typo in a column name surfaces inline rather than silently producing wrong rows.

4. Wire the output node

Connect your last node to the Output node. The output panel is the endpoint contract: pick which fields are exposed, set their public aliases, and mark the root entity. The Try-It panel below the editor calls the endpoint live with your auth and shows the JSON response — verify before you share the URL.

5. Deploy

Hit Deploy in the top bar. You get a URL of the form:

https://api.quiltapi.com/data/v1/{handle}/{workspace}/{canvas-slug}

Choose Private (requires X-API-Key header) or Public (anyone with the URL). The deploy modal generates the API key and renders a curl example you can copy.

curl -H "X-API-Key: $QUILTAPI_KEY" \
  "https://api.quiltapi.com/data/v1/me/default/orders-enriched?filter[status]=paid"

Every response has the same envelope: rows live under data.<source name> (for example response.data.orders), pagination and freshness are in meta, and endpoints with aggregate nodes add an aggregates block. Source names are snake_case and come from the source node's name in the editor.

{
  "data": { "orders": [ { "order_id": "O-58210", "amount": 1249.5 } ] },
  "meta": {
    "page": 1,
    "page_size": 50,
    "sources": { "orders": { "total": 812, "has_more": true } },
    "fetched_at": "2026-10-06T09:12:00+00:00",
    "stale": false
  }
}

Filtering, sorting, pagination

Every endpoint accepts these query parameters out of the box:

  • filter[field]=value — exact match
  • filter[field][gte]=value — operator-based (also lt, lte, gt, ne, in, contains)
  • sort=field · order=asc|desc
  • page=1 · page_size=50 (capped at 100)
  • fields=name,email — return only those keys per row in every data slot (matches response keys exactly, top-level only)

Responses carry an ETag header — send it back as If-None-Match to get 304 Not Modified with an empty body when nothing changed.

Common errors

If you see…Try this
Couldn't detect any columnsThe source returned no rows or no header row was found. For Sheets, confirm the header row index. For REST, check the response shape — see the REST API guide.
A source named 'X' already existsPick a different name. Source names are unique per user, so you can't reuse the same name across workspaces either.
Tier limit reached: too many sourcesUpgrade at /pricing or delete an unused source.

Where to next

Pick a connector and follow the deeper guide: Google Sheets · REST API.

See also: Google Sheets · REST API