SOURCE_ID: import_from_google_sheets NAME: Import Google Sheets CATEGORY: CRM Import rows from a Google Sheets spreadsheet tab into Floqer — either as a one-time backfill or as an ongoing source that picks up newly added rows. Imported rows become available to your Floqer workflows for enrichment, scoring, outreach, and the like. INDEX: 1. Endpoints 2. Pull mode (one-time vs ongoing) 3. Body shape (preview + create) 4. Field catalogue 5. Dynamic options 6. How to configure end-to-end 7. Key notes 8. Where it fits 9. When to use ================================================================================ 1. ENDPOINTS ================================================================================ Source identifier (used in every endpoint path): `import_from_google_sheets`. POST /api/v1/sources/import_from_google_sheets/preview Scope: sources:read Returns a sample page of rows from the chosen sheet tab, without creating anything. Use this to validate the spreadsheet / tab selection and inspect column shape before committing. POST /api/v1/sources/import_from_google_sheets Scope: sources:write Creates the source, imports existing rows immediately (when `import_existing_data`), and — for an active source — picks up newly added rows going forward. Returns `source_instance_id` (the new source's UUID). POST /api/v1/sources/import_from_google_sheets/options/ Scope: sources:read Resolves dynamic option values for a field. Two `field_name` values matter: `spreadsheet_id` and `sheet_name` (see §5). GET /api/v1/sources//data Scope: sources:read Paginated rows imported into the created source. `` is the UUID returned by Create. Query: `page_no` (default 1), `page_size` (default 20, max 200). Source-agnostic; see concepts.txt §10. POST /api/v1/sources//sync Scope: sources:write Connects the created source to a workflow and (by default) backfills it with the source's current rows. `` here is the UUID returned by Create. Body: { workflow_id, field_mapping, push_existing?, run? } — `field_mapping` keys are `input.` references on the target workflow, values are the source fields to pull. This step is source-agnostic; see concepts.txt §10 for the full shape. PATCH /api/v1/sources//status Scope: sources:write Pause or resume an active source by UUID. Body: {"status": "active" | "paused"}. Source-agnostic. Every endpoint for this source first verifies the API-key user has an active Google Sheets connection. Missing connection → 424. ================================================================================ 2. PULL MODE (ONE-TIME VS ONGOING) ================================================================================ `pull_mode` is required on the create endpoint (not on preview). Values: "static" One-time import. The source imports the sheet's current rows once (when `import_existing_data`) and stops — it does not watch for new rows. "active" Ongoing source. Imports the current rows initially (when `import_existing_data`) AND picks up newly added rows as they appear, until `expiration_date`. ================================================================================ 3. BODY SHAPE (PREVIEW + CREATE) ================================================================================ Field names are snake_case. Unknown top-level keys are rejected with 400 — the body is strict. Preview accepts: spreadsheet_id required: the Google Spreadsheet ID sheet_name required: the tab name within the spreadsheet import_existing_data boolean; optional trigger_column string; optional Create accepts all the preview fields plus: name required: display name for the new source pull_mode required: "static" | "active" expiration_date ISO date (YYYY-MM-DD); optional (active source only) ================================================================================ 4. FIELD CATALOGUE ================================================================================ spreadsheet_id (string) — required The Google Spreadsheet ID. Resolve it with the `spreadsheet_id` dynamic-options call (§5). sheet_name (string) — required The tab name within the spreadsheet (not a numeric sheet id). Resolve it with the `sheet_name` dynamic-options call, passing the chosen `spreadsheet_id` as context (§5). import_existing_data (boolean) — optional When true, the rows already present in the sheet are imported. Leave it on to backfill; turn it off when you only care about rows added going forward (active source). trigger_column (string) — optional The column used to detect newly added rows for an active source. A new row is picked up when this column is populated. name (string) — required on create only Human-readable display name for the source. pull_mode (string) — required on create only "static" (one-time) or "active" (ongoing, watches for new rows). See §2. expiration_date (string) — optional, active only ISO date (YYYY-MM-DD) after which an active source stops watching for new rows. ================================================================================ 5. DYNAMIC OPTIONS ================================================================================ Two dynamic-options field names are available for this source. Both are POSTs to /api/v1/sources/import_from_google_sheets/options/ with body `{ "context"?: {...} }`. spreadsheet_id Context: none. Returns: {value: , label: , extras}. Use the returned `value` directly as `spreadsheet_id`. sheet_name Context: { "spreadsheet_id": "" } — REQUIRED. Returns: {value: , label: , extras}. Use the returned `value` directly as `sheet_name`. Connection check: each call verifies the API-key user has an active Google Sheets connection first. Missing connection → 424. ================================================================================ 6. HOW TO CONFIGURE END-TO-END ================================================================================ Typical flow for an AI agent building a Google Sheets import source: Step 1 — Resolve the spreadsheet POST /api/v1/sources/import_from_google_sheets/options/spreadsheet_id Body: {} Pick the spreadsheet's `value` as `spreadsheet_id`. Step 2 — Resolve the tab POST /api/v1/sources/import_from_google_sheets/options/sheet_name Body: {"context": {"spreadsheet_id": ""}} Pick the tab's `value` as `sheet_name`. Step 3 — Preview before committing POST /api/v1/sources/import_from_google_sheets/preview Body: { "spreadsheet_id": "", "sheet_name": "Sheet1", "import_existing_data": true } Check the returned `data[]` row shape (one key per sheet column). Iterate until you're happy — preview never creates anything. Step 4 — Create the source POST /api/v1/sources/import_from_google_sheets Body: + the create-only fields: "name": "", "pull_mode": "static" | "active", "expiration_date": "2027-01-01" // optional, active only Response: { "status": 201, "data": { "source_instance_id": "", "name", "created_at" }} Step 4b — (Optional) Poll imported rows while the import runs GET /api/v1/sources//data?page_no=1&page_size=20 ( = UUID from Step 4) Row keys match the sheet's column headers. `total_count` grows until the import finishes. Step 5 — Sync the source into a workflow (so its rows flow downstream) POST /api/v1/sources//sync ( = UUID from Step 4 ) First build `field_mapping`: a. GET /api/v1/workflows → pick the destination workflow_id. b. GET /api/v1/workflows//sheets//inputs → each input has a `reference` like `{{input.email}}`. c. Map each workflow input (reference WITHOUT braces) to a source field — the source fields are the sheet's column headers. Body: { "workflow_id": "", "field_mapping": { "input.email": "Email", "input.name": "Name" }, "push_existing": true, "run": "all" } See concepts.txt §10 for the full sync semantics (source-agnostic). The initial import runs asynchronously — the create call returns as soon as the source is created and the import has started, not when rows have finished arriving. ================================================================================ 7. KEY NOTES ================================================================================ - Google Sheets connection is mandatory. If the API-key user has no active Google Sheets connection, every endpoint (preview, create, options) returns 424 ("User is not connected to 'googleSheets'."). Surface this as a "connect Google Sheets first" CTA. - `sheet_name` is the tab NAME (e.g. "Sheet1"), not a numeric sheet id. Use the `sheet_name` dynamic-options call to get exact names. - An active source watches for newly added rows. `trigger_column` controls which column's presence marks a row as new. - `import_existing_data` controls whether the rows already in the sheet are backfilled on create. - Credits are consumed when the source is created. If credit consumption fails (e.g. insufficient balance), the source is still created but its import can't start; the API returns 402 so you can top up and retry. - Use PATCH /status to pause an active source and resume it later without recreating it. ================================================================================ 8. WHERE IT FITS ================================================================================ UPSTREAM (in Google Sheets) Rows live in a spreadsheet tab in the user's Google account. Column headers become the field names on imported rows. THIS SOURCE Creates a Google Sheets import source. On creation it imports the sheet's current rows (when `import_existing_data`); an active source also picks up newly added rows until `expiration_date`. DOWNSTREAM (in Floqer) Imported rows become available to your Floqer workflows — wire the source into a workflow to enrich, score, or run outreach on each row. ================================================================================ 9. WHEN TO USE ================================================================================ - One-time backfill of a spreadsheet into a Floqer workflow: `pull_mode: static`, `import_existing_data: true`. - Watch a spreadsheet for new rows and run a workflow on each one as it's added: `pull_mode: active`, `trigger_column: ""`. When you instead want to push data OUT of Floqer INTO a sheet, use the Google Sheets action templates (e.g. `google_sheet_add_data`, `google_sheet_upsert_row`) inside a workflow — see the action catalog in llms-full.txt. ================================================================================ Last updated: 2026-06-02. Reference: https://floqer.com/docs/reference