Floqer Public API — Complete Reference for AI Agents API endpoint base URL: https://api.floqer.com/api/v1 (for /api/v1/... endpoint paths in this file; all other URLs are absolute) Authentication: Bearer token. All requests require Authorization: Bearer floq_YOUR_API_KEY Rate limits: 200 requests/minute, 10,000 requests/day per API key. ================================================================================ FILE MAP — READ IN THIS ORDER ================================================================================ https://floqer.com/docs/llms-full.txt — You are here. The master reference. https://floqer.com/docs/concepts.txt — How Floqer works. Mental model, vocabulary, data types. https://floqer.com/docs/action-catalog.txt — Find the right action for your data. https://floqer.com/docs/action-detail/{id}.txt — Full spec for a specific action. https://floqer.com/docs/use-case-catalog.txt — End-to-end workflow recipes indexed by GTM problem. https://floqer.com/docs/use-case-detail/{slug}.txt — Full recipe for one use case (chain of actions + narrative). https://floqer.com/docs/openapi.json — Machine-readable OpenAPI 3.0 spec. Use when you have OpenAPI tooling; otherwise stay in this file. https://floqer.com/docs.md — Thin pointer page. Just routes you to llms-full.txt (this file) and openapi.json. No content of its own. https://floqer.com/docs/reference — HTML page (not plain text). Human-readable single-page API reference with every endpoint, parameters, schemas, and curl examples. Open in a browser. ================================================================================ REQUIRED READING — https://floqer.com/docs/concepts.txt ================================================================================ Before using the endpoints below, fetch https://floqer.com/docs/concepts.txt. It is the single source of truth for Floqer's mental model and vocabulary: 1. Workflows and Sheets — container model, main sheet, sheet-scoped paths 2. Inputs — columns, types, reference strings 3. Actions — action_id vs action_instance_id, reference outputs 4. Data Types — scalars (string, url, email, number, boolean) for inputs and outputs; nested types (raw_array, json, structured_array) for action outputs only 5. Variable References — {{input.field}} and {{action_id.field}} syntax; structured_array column refs ({{action_id.list.column}}) 6. Action Chain — execution order, filter, push_data_to_sheet 7. Running a Workflow — add rows, run, check results, cache settings 8. Get Action Field Options — resolve dynamic dropdowns before configuring an action The endpoint reference below assumes this mental model. Do not skip it. ================================================================================ QUICK START — BUILD AND RUN A WORKFLOW ================================================================================ 1. Create a workflow POST /api/v1/workflows {"name": "Lead Enrichment Pipeline"} → returns workflow_id (this is also the main sheet's sheet_id) 2. Add inputs to the main sheet POST /api/v1/workflows/{workflow_id}/sheets/{workflow_id}/inputs [{"name": "linkedin_url", "type": "url"}, {"name": "company_name", "type": "string"}] → returns inputs with reference strings: {{input.linkedin_url}} 3. Find the right action Read https://floqer.com/docs/action-catalog.txt — match your input types to action "Needs" 4. Add an action to the main sheet POST /api/v1/workflows/{workflow_id}/sheets/{workflow_id}/actions/add {"action_id": "enrich_company_linkedin_profile"} → returns action_instance_id, inputs to configure, outputs with references 5. Configure the action PATCH /api/v1/workflows/{workflow_id}/sheets/{workflow_id}/actions/{action_instance_id} {"inputs": {"linkedin_url": "{{input.linkedin_url}}"}} 6. Add data rows (start with 10–50 during build; use run_after_add="first_10" to verify safely) POST /api/v1/workflows/{workflow_id}/sheets/{workflow_id}/rows {"rows": [{"linkedin_url": "https://linkedin.com/company/floqer", "company_name": "Floqer"}], "run_after_add": "first_10"} → returns {row_ids: [...], rows_queued_for_run: 1} 7. Run POST /api/v1/workflows/{workflow_id}/sheets/{workflow_id}/run {"row_ids": ["returned-row-id"]} 8. Check results POST /api/v1/workflows/{workflow_id}/sheets/{workflow_id}/rows/list {"row_ids": ["returned-row-id"]} // or empty body to browse all rows paginated ================================================================================ ENDPOINTS — BUILD A WORKFLOW ================================================================================ Inputs (sheet-scoped) --------------------- GET /api/v1/workflows/{workflow_id}/sheets/{sheet_id}/inputs — List Inputs Returns current input fields with reference strings. POST /api/v1/workflows/{workflow_id}/sheets/{sheet_id}/inputs — Add Inputs Body: JSON array of {name, type, description?} Response: [{name, type, description, reference}] DELETE /api/v1/workflows/{workflow_id}/sheets/{sheet_id}/inputs/{field_name} — Delete Input Removes an input. Breaks action references to {{input.field_name}}. Actions (sheet-scoped) ---------------------- POST /api/v1/workflows/{workflow_id}/sheets/{sheet_id}/actions/add — Add Action to Workflow Adds an action to the chain. Returns action_instance_id, inputs to configure, and outputs with reference strings. Body: {action_id, after?, name?} `after` (optional) is the immediate predecessor at insertion time — the new action goes right after the named anchor and everything previously downstream of that anchor shifts down by one. To chain N actions sequentially in a single batch, set `after` of each call to the `action_instance_id` returned by the previous call. Repeated calls with the same `after` value (e.g. `after: "input"` N times) produce a chain in REVERSE of call order, because each new action is inserted immediately after the anchor and pushes the previously-inserted one further down. `name` (optional) overrides the action template's default display name. Whitespace-only values are ignored. The actual stored value is returned in `display_name` on the response. PATCH /api/v1/workflows/{workflow_id}/sheets/{sheet_id}/actions/{action_instance_id} — Configure Action Wires input variables to the action's fields. Body: {inputs?, run_if?, continue_workflow_if_action_fails?, note?} `note` (optional) saves a free-text note on the action — same upsert as Save Action Note. Whitespace-only values are ignored. PATCH /api/v1/workflows/{workflow_id}/sheets/{sheet_id}/actions/{action_instance_id}/name — Rename Action Sets an action instance's display name. Single-field PATCH — the only body field is `name` (required, trimmed, non-empty). Body: {name: string} Renaming does NOT invalidate the row-level cache for this action — display name doesn't change what the action does. Only the workflow's `updated_at` timestamp is bumped. Reserved `action_instance_id` values (`"input"`, `"graph"`) return 404. Response: {status, data: {action_instance_id, display_name}}. PATCH /api/v1/workflows/{workflow_id}/sheets/{sheet_id}/actions/{action_instance_id}/move — Move Action Re-orders an action within the sheet's chain. Updates the chain pointers (`nextAction` / `prevAction`) on the moved action, on its old neighbours (relinked so the chain skips it at the source position), and on its new neighbours (relinked so the chain points through it at the destination position). The action's configured inputs / outputs are not touched. Body: {after: string} -- required • "input" → move to the start (right after the synthetic input node) • → move immediately after that instance `after` cannot equal the action being moved. Cannot move `id1` (the input node — chain anchor); reserved values `"input"` / `"graph"` return 404. Reference safety: Move does NOT rewrite configured inputs. If the new position pushes the action ahead of one of its upstream references — or pushes a downstream consumer ahead of this action — those refs will fail at run time. Fix afterwards via Configure Action. Response: {status, data: {moved: true, action_instance_id, after}}. `after` in the response is the canonical public form — `"input"` when the action is now at the start of the chain. DELETE /api/v1/workflows/{workflow_id}/sheets/{sheet_id}/actions/{action_instance_id} — Delete Action Removes an action from the sheet's chain by relinking its previous and next neighbours so the chain skips it. The deleted action's configured inputs / outputs are gone. Cannot delete the input node — pass any other `action_instance_id`. Reserved values (`"input"`, `"graph"`) return 404. No request body. Response: {status, data: {deleted: true, action_instance_id, dependent_actions}}. `dependent_actions[]` lists every action whose configuration referenced one of the deleted action's outputs. Each entry carries `action_instance_id` plus an `inputs` object containing ONLY the affected field keys (snake-cased); values are the stored references translated to public reference form so the broken refs are obvious. Unrelated fields on the same dependent action are not included. Empty array when nothing depended on the deleted action. Reference safety: any field surfaced in `dependent_actions[]` now contains an `unresolved_reference` to the deleted action. Fix each via Configure Action before the next row run, otherwise those rows will fail. POST /api/v1/workflows/{workflow_id}/sheets/{sheet_id}/actions/{action_instance_id}/notes — Save Action Note Saves a free-text note on an action instance. Upsert against the composite primary key `(action_instance_id, sheet_id)` on `public_api_notes` — calling again for the same action overwrites the existing note. Notes are surfaced on Get Action and on each node of Get Action Graph as `note` (absent when no note has been saved). Body: {note: string} -- required, trimmed, non-empty Response: {status, data: {action_instance_id, sheet_id, note}}. GET /api/v1/workflows/{workflow_id}/sheets/{sheet_id}/actions/graph — Get Action Graph Returns every node in the sheet (input node + actions) in topological execution order, each with its {{reference}} strings and next-edge topology. Each node also carries `note` when one has been saved on the action via Save Action Note or Configure Action. GET /api/v1/workflows/{workflow_id}/sheets/{sheet_id}/actions/{action_instance_id} — Get Action Returns a single action's node shape. Same schema as one node of Get Action Graph (so any saved note is included as `note`). Round-trips with Configure Action on the same URL. Includes validation warnings for broken references. Readback caveat for structured-output actions (`llm_models`, `llm_web_agents`): the `output_format` field in this response is a type DISCRIMINATOR string — `"fields"` for the structured-fields form, `"json"` for raw JSON — NOT the schema object you sent in Configure Action. The persisted schema is not echoed back through Get Action. To verify what fields the action will emit, look at `outputs[]` (or call Get Action Outputs on the same instance). POST /api/v1/workflows/{workflow_id}/sheets/{sheet_id}/actions/{action_instance_id}/options/{field_name} — Get Action Field Options Resolves a dynamic dropdown for the named field. Required before configuring any action that has a dynamicDropdown / spreadsheetsDropdown / hubspot_properties_dropdown / externalIdDropdown / inSheetDropdown / etc. Body: {"context"?: {"": ""}} Some fields depend on other selections — e.g. hubspot_object_properties needs {"context": {"hubspot_object": "contacts"}}. Pass {} when no context is required. Response: {"options": [{value, label}, ...]}. Pass the chosen `value` directly into the matching field in Configure Action. See per-action HOW TO CONFIGURE in https://floqer.com/docs/action-detail/{action_id}.txt for the exact pre-call(s) each action needs. GET /api/v1/workflows/{workflow_id}/sheets/{sheet_id}/actions/{action_instance_id}/outputs — Get Action Outputs Returns the resolved output schema for an action — every field it produces, each with a ready-to-paste `reference` token for downstream wiring. No request body. Static actions (Salesforce / HubSpot / etc.) carry their schema from the moment they're added — calling this on a static action is fine but not necessary; the same `outputs[]` is on Get Action / Get Action Graph. Dynamic-output actions (`http_api_call`, `raw_to_structured_array`) only know their output shape after a row runs. The discovery sequence is: 1. Configure the action with realistic inputs (Configure Action). 2. Add ONE example row whose data exercises the action, then Run Rows on just that row. The action's worker stores the upstream response under `action.ping`. 3. Call Get Action Outputs. The handler reads the captured `ping`, derives the field/column schema, mints stable `responseId`s, persists the new schema onto the action, and returns it. 4. ⚠ The example row from step 2 ran BEFORE the schema existed — its cell in List Rows will not surface the discovered outputs (the runtime had no response to associate values with). To get a row whose cell carries the typed outputs, either re-run the example row (Run Rows again) or delete it (Delete Rows) and run fresh rows. From this point on every new run sees the persisted schema. See https://floqer.com/docs/action-detail/http_api_call.txt and https://floqer.com/docs/action-detail/raw_to_structured_array.txt for the per-action walkthrough. Sheets (workflow-scoped) ------------------------ POST /api/v1/workflows/{workflow_id}/sheets — Create Sheet Body: {name, auto_run?, cache_enabled?, cache_since?} Returns: full sheet object {sheet_id, workflow_id, name, auto_run, cache_enabled, cache_since} GET /api/v1/workflows/{workflow_id}/sheets — List Sheets Returns all sheets in the workflow, including the main sheet. data[0] is always the main sheet (sheet_id === workflow_id, is_main_sheet: true). Additional sheets follow in creation order. ================================================================================ ENDPOINTS — RUN A WORKFLOW ================================================================================ POST /api/v1/workflows/{workflow_id}/sheets/{sheet_id}/rows — Add Rows Body: {rows: [{: , ...}], run_after_add?: "none" | "first_10" | "all"} Response: {row_count, row_ids: [...], rejected: [{row: {...original payload...}, errors: [...]}], rows_queued_for_run} No type validation — values written as-is; type issues surface at action runtime. Missing fields → null. Unknown fields → row echoed in rejected with error details. Partial success, never atomic. row_ids pipes directly into Run Rows's row_ids. run_after_add is scoped to THIS call's rows only — pre-existing rows on the sheet are not touched. Max 1,000 rows per call. POST /api/v1/workflows/{workflow_id}/sheets/{sheet_id}/run — Run Rows Body: {row_ids: ["id1", "id2"]} -- specific rows OR {first_10: true} -- shortcut: first 10 rows on the sheet (by created_at asc) Exactly one of row_ids or first_10 required. Both or neither → 400. Execution is async — returns immediately. Response: {status, message, data: {rows_queued}}. POST /api/v1/workflows/{workflow_id}/sheets/{sheet_id}/run-all — Run All Rows No body required. Queues every row on the sheet. ⚠️ Full credit cost = row_count × actions. Never call without first verifying on a sample. Response: {status, message, data: {rows_queued}}. POST /api/v1/workflows/{workflow_id}/sheets/{sheet_id}/actions/{action_instance_id}/run — Run Action Runs a specific action against a set of rows. By default ONLY the targeted action runs — downstream actions are not touched. Set `run_next_action: true` to continue down the chain after this action finishes, re-running every action wired off its outputs. Body: {row_ids: [...], run_next_action?: boolean} `row_ids` is required. Pass `[]` to queue every row on the sheet (analogous to Run All Rows but scoped to one action). Pass explicit IDs (from Add Rows / List Rows) to target a subset. `run_next_action` `false` (default) → just this action; `true` → this action plus everything downstream. Useful after Configure Action when you want to refresh a single action and everything wired off its outputs in one call. Reserved `action_instance_id` values (`"input"`, `"graph"`) return 404. Async — returns immediately. Response: {status, message, data: {rows_queued}}. POST /api/v1/workflows/{workflow_id}/sheets/{sheet_id}/rows/list — List Rows POST (not GET) — request body carries filter + pagination so large row_id arrays don't overflow the URL. Body (all optional): {row_ids?: [...] (max 200), page_no?: 1, page_size?: 20 (max 200)} Omit row_ids to browse all rows on the sheet (paginated). Include row_ids to fetch just those. Response envelope (full shape): { "status": 200, "data": { "rows": [...], // RowView[], one per row on this page "total_count": , // total rows being paginated — sheet-wide // count in browse mode, or the size of the // `row_ids` filter you passed "page_no": , // echoes back the requested page (default 1) "page_size": // echoes back the requested page size (default 20) } } Each row (RowView): {row_id, row_status, created_at (ISO 8601 UTC), inputs, cells}. row_status: "pending" (never run) | "running" (any cell queued/running) | "complete" (all cells complete) | "has_failures" (terminal, at least one cell failed or errored). cells: object keyed by `action_instance_id` (the public form, exactly the same ID Add Action / Get Action returned). Empty {} for rows that have never been run. Each cell: {status: "queued"|"running"|"complete"|"failed"|"error"|"condition_not_met", outputs?: {...}, outputs_ref?: {url, size_bytes}, error?: string}. `failed` and `error` are both terminal failure states — `failed` is a known failure path (provider 404, validation rejected); `error` is an unexpected runtime error. Both carry an `error` message; treat them the same when polling for completion. `outputs` keys are the action's snake-cased public output names — same keys you'd see in the Add Action `outputs[].name` and the `{{ref}}` token after the dot. `outputs` (inline) and `outputs_ref` (large-payload URL — fetch with API key) are mutually exclusive. `structured_array` outputs (e.g. `list_of_employees`) come back as a flat array of objects keyed by the column's snake_case name — `[{first_name: "Satya", last_name: "Nadella", ...}, ...]` — NOT the engine's internal numbered-map storage shape. Empty / missing values for an output may surface as `""` rather than the typed empty (e.g. `[]` for arrays, `null` for booleans). Treat all outputs as nullable on the consumer side. Poll this after runRows; branch on row_status for the quick check, cells[action_id].status for per-cell detail. POST /api/v1/workflows/{workflow_id}/sheets/{sheet_id}/rows/delete — Delete Rows Body: {row_ids: ["uuid1", "uuid2", ...]} (max 200). Response: {deleted_count, deleted_row_ids: [...], rejected: [{row_id, error}]}. Partial success — UUIDs not found on this sheet come back in rejected. Cannot be undone. POST /api/v1/workflows/{workflow_id}/sheets/{sheet_id}/rows/delete-all — Delete All Rows No body required. Deletes every row on the sheet. Cannot be undone. Response: {deleted_count}. ================================================================================ ENDPOINTS — MANAGE WORKFLOWS ================================================================================ POST /api/v1/workflows — Create Workflow Body: {name} Returns: {workflow_id, name, created_at} — workflow_id is also the main sheet's sheet_id. GET /api/v1/workflows — List Workflows Returns all workflows in the organization as summaries: [{workflow_id, name, created_at, updated_at, last_run_at}]. last_run_at is null for workflows that have never been run. DELETE /api/v1/workflows/{workflow_id} — Delete Workflow Deletes the workflow and all its sheets, inputs, actions, rows, and run history. Cannot be undone. Returns: {workflow_id, deleted: true}. ================================================================================ UI LINKS — PRESENTING WORKFLOWS TO THE USER ================================================================================ When directing a user to view a workflow in the UI, construct a full link with view + sheet — the bare `/workflow/{id}` redirects to the build view of the main sheet, which is usually not specific enough. URL template: https://app.floqer.com/workflow/{workflow_id}?action={view}&v2=true&sheetId={sheet_id} Path and query parameters: workflow_id UUID. Required. action=build Node-graph view. UI label "Floq". Surface after chain edits or when the user is auditing pipeline shape. action=table Spreadsheet view. UI label "Data". Surface after row runs or when the user is reviewing per-row outputs. v2=true Required UI version flag. sheetId UUID. Required. Equal to workflow_id for the main sheet; a different UUID for sub-sheets created via POST /workflows/{id}/sheets. Always include — the bare link redirects to the main sheet. UI label ≠ URL param. The UI labels these views "Floq" (build) and "Data" (table). When writing to the user, refer to them by their UI labels — "here's the Floq view of the chain", "results are in the Data view" — not by the URL params, which the user isn't seeing. Defaults: - Reporting chain edits → Floq link - Reporting row results → Data link - Touching a sub-sheet → link directly to that sub-sheet's Data view (sheetId = sub-sheet UUID), not the parent main sheet Examples: Floq (chain): https://app.floqer.com/workflow/?action=build&v2=true&sheetId= Data (rows): https://app.floqer.com/workflow/?action=table&v2=true&sheetId= Sub-sheet rows: https://app.floqer.com/workflow/?action=table&v2=true&sheetId= When linking both views in one response, label clearly: - Floq (build view): - Data (table view): ================================================================================ ERRORS ================================================================================ Success: {"status": 200, "data": {...}} Single errors (401, 403, 404, 429, 500): {"status": 401, "error": "Unauthorized", "message": "API key is required"} Validation errors (400) — all field errors at once: {"status": 400, "error": "Validation Error", "message": "2 validation errors", "errors": [{"field": "name", "message": "required"}]} 429 includes retryAfter: {"status": 429, "error": "Too Many Requests", "message": "...", "retryAfter": 42} ================================================================================ This file is maintained manually. Last updated: 2026-05-19. Full interactive reference: https://floqer.com/docs/reference