Fillo Integrations API
The Integrations API from Fillo — 8 operation(s) for integrations.
Operations 11
PUT
/api/v1/manage/forms/{form}/integrations/{provider}
Enable or reconfigure a form's destination
#
The Integrations API from Fillo — 8 operation(s) for integrations.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/fillo-so:fillo-so-integrations-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Fillo So Integrations API
version: 1.0.0
contact:
name: Fillo support
email: hello@fillo.so
url: https://fillo.so/developers
description: 'Operations tagged Integrations across 2 of this provider''s published API definitions: fillo-so-openapi.json, fillo-so-openapi.json. Each path carries the servers of the definition it was published in.'
servers:
- url: https://fillo.so
security:
- bearerAuth: []
tags:
- name: Integrations
paths:
/api/v1/manage/forms/{form}/integrations/{provider}:
get:
tags:
- Integrations
summary: Get a form's destination
operationId: getFormIntegration
description: 'Whether this form sends responses to the provider, and with what configuration. Scope: integrations:manage.'
parameters:
- $ref: '#/components/parameters/FormHandle'
- name: provider
in: path
required: true
description: google_sheets, notion, slack, or hubspot. Discord destinations are managed with `fillo discord`.
schema:
type: string
enum:
- google_sheets
- notion
- slack
- hubspot
responses:
'200':
description: The form's destination for this provider.
content:
application/json:
schema:
$ref: '#/components/schemas/FormIntegration'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/RateLimited'
put:
tags:
- Integrations
summary: Enable or reconfigure a form's destination
operationId: setFormIntegration
description: 'Start sending this form''s responses to the provider, or change how. Respondent answers leave Fillo and land in that account, so this is outward-facing (Tier B). Writable keys per provider: google_sheets `spreadsheetId` and `sheetTabId` (omit both to create a new spreadsheet); notion `titleFieldId`; slack `slackChannelId` and `slackIncludeFieldIds`; hubspot `hubspotEmailFieldId` (required), `hubspotMappings`, `hubspotCreateMarketableContact`, `hubspotCompany`, and `hubspotDeal` — HubSpot is saved whole, so a workflow you stop naming is dropped. An unknown key is a 400. Scope: integrations:manage.'
parameters:
- $ref: '#/components/parameters/FormHandle'
- name: provider
in: path
required: true
description: google_sheets, notion, slack, or hubspot. Discord destinations are managed with `fillo discord`.
schema:
type: string
enum:
- google_sheets
- notion
- slack
- hubspot
requestBody:
required: false
content:
application/json:
schema:
type: object
description: The provider's writable config keys. An empty object enables with defaults where the provider allows it.
responses:
'200':
description: The form's destination after the change.
content:
application/json:
schema:
$ref: '#/components/schemas/FormIntegration'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'413':
$ref: '#/components/responses/PayloadTooLarge'
'429':
$ref: '#/components/responses/RateLimited'
delete:
tags:
- Integrations
summary: Stop a form's destination
operationId: disableFormIntegration
description: 'Stop sending this form''s responses to the provider. Records already created stay where they are, and the workspace connection is untouched, which keeps this routine (Tier A). Scope: integrations:manage.'
parameters:
- $ref: '#/components/parameters/FormHandle'
- name: provider
in: path
required: true
description: google_sheets, notion, slack, or hubspot. Discord destinations are managed with `fillo discord`.
schema:
type: string
enum:
- google_sheets
- notion
- slack
- hubspot
responses:
'200':
description: The destination, now disabled.
content:
application/json:
schema:
$ref: '#/components/schemas/FormIntegration'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'429':
$ref: '#/components/responses/RateLimited'
servers:
- url: https://fillo.so
/api/v1/manage/integrations/connections:
get:
tags:
- Integrations
summary: List integration accounts
operationId: listIntegrationConnections
description: 'The workspace''s connected provider accounts, which one the key''s project uses for each provider, and the connected Discord servers. `label` is also the exact string an account removal must confirm with. Scope: integrations:manage.'
responses:
'200':
description: The workspace's integration accounts.
content:
application/json:
schema:
$ref: '#/components/schemas/IntegrationConnections'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/RateLimited'
servers:
- url: https://fillo.so
/api/v1/manage/integrations/connections/{provider}:
put:
tags:
- Integrations
summary: Select the account a project uses
operationId: selectIntegrationConnection
description: 'Point the key''s project at one of the workspace''s provider accounts. Accounts belong to the workspace and are selected per project, so one install can serve several projects. Scope: integrations:manage.'
parameters:
- name: provider
in: path
required: true
description: notion, slack, hubspot, or discord.
schema:
type: string
enum:
- notion
- slack
- hubspot
- discord
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- connectionId
properties:
connectionId:
type: string
minLength: 1
responses:
'200':
description: The accounts, with the new selection applied.
content:
application/json:
schema:
$ref: '#/components/schemas/IntegrationConnections'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'413':
$ref: '#/components/responses/PayloadTooLarge'
'429':
$ref: '#/components/responses/RateLimited'
delete:
tags:
- Integrations
summary: Detach a project's selected account
operationId: detachIntegrationConnection
description: 'Detach the key''s project from its selected account for one provider: every form in the project that sends to it stops delivering immediately. The workspace-level account survives for sibling projects — only the destinations pinned to that exact account in this project are removed. Outward-facing (Tier B): the key holder chose integrations:manage at mint. Scope: integrations:manage.'
parameters:
- name: provider
in: path
required: true
description: notion, slack, hubspot, or discord.
schema:
type: string
enum:
- notion
- slack
- hubspot
- discord
responses:
'200':
description: The accounts, with the count of form destinations removed from this project.
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/IntegrationConnections'
- type: object
required:
- removedDestinations
properties:
removedDestinations:
type: integer
description: Form destinations pinned to the detached account that were removed from this project.
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'429':
$ref: '#/components/responses/RateLimited'
servers:
- url: https://fillo.so
/api/v1/manage/integrations/accounts/{id}:
delete:
tags:
- Integrations
summary: Remove a connected account
operationId: removeIntegrationAccount
description: 'Permanently remove one reusable provider account from the key''s workspace. Its stored credential is revoked and every project selection and form destination pinned to it cascades away — across every project — so this is destructive (Tier C): `confirm` must equal the account''s exact `label` from the connections listing. Scopes: integrations:manage AND workspace:manage; the key acts as the human who minted it and is refused (403) once that person is no longer an owner or admin.'
parameters:
- name: id
in: path
required: true
description: An integration account id from the connections listing.
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ConfirmTarget'
responses:
'200':
description: The account was removed.
content:
application/json:
schema:
type: object
required:
- removed
- id
- provider
- label
properties:
removed:
type: boolean
enum:
- true
id:
type: string
provider:
type: string
enum:
- notion
- slack
- hubspot
- discord
label:
type: string
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'413':
$ref: '#/components/responses/PayloadTooLarge'
'429':
$ref: '#/components/responses/RateLimited'
servers:
- url: https://fillo.so
/api/v1/manage/integrations/discord/accounts/{id}:
patch:
tags:
- Integrations
summary: Rename a connected Discord channel
operationId: renameDiscordChannel
description: 'Name, or with an empty value un-name, one connected Discord channel. Member-visible copy only — nothing re-delivers, so this is routine (Tier A). Scope: integrations:manage.'
parameters:
- name: id
in: path
required: true
description: A Discord account id from the connections listing.
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- label
properties:
label:
type: string
description: An empty string clears the name.
responses:
'200':
description: The channel's new label.
content:
application/json:
schema:
type: object
required:
- id
- label
properties:
id:
type: string
label:
type: string
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'413':
$ref: '#/components/responses/PayloadTooLarge'
'429':
$ref: '#/components/responses/RateLimited'
servers:
- url: https://fillo.so
/api/v1/manage/integrations/discord/servers/{guildId}:
delete:
tags:
- Integrations
summary: Disconnect a Discord server
operationId: disconnectDiscordServer
description: 'Disconnect one Discord server. Its guild connection and every channel webhook Fillo holds there go together, and their pinned form destinations cascade away across every project, so this is destructive (Tier C): `confirm` must equal the server id. Scopes: integrations:manage AND workspace:manage; the key acts as the human who minted it and is refused (403) once that person is no longer an owner or admin.'
parameters:
- name: guildId
in: path
required: true
description: A connected Discord server (guild) id.
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ConfirmTarget'
responses:
'200':
description: The server was disconnected.
content:
application/json:
schema:
type: object
required:
- disconnected
- guildId
- name
properties:
disconnected:
type: boolean
enum:
- true
guildId:
type: string
name:
type:
- string
- 'null'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'413':
$ref: '#/components/responses/PayloadTooLarge'
'429':
$ref: '#/components/responses/RateLimited'
servers:
- url: https://fillo.so
/api/v1/manage/integrations/hubspot/properties:
get:
tags:
- Integrations
summary: List HubSpot Contact properties
operationId: listHubspotProperties
description: 'The connected account''s writable Contact properties, so a mapping can be built without guessing internal names. `email` is handled separately and is not listed. Scope: integrations:manage.'
responses:
'200':
description: Writable Contact properties.
content:
application/json:
schema:
type: object
required:
- properties
properties:
properties:
type: array
items:
type: object
required:
- property
- label
- type
- fieldType
- options
properties:
property:
type: string
label:
type: string
type:
type: string
enum:
- string
- number
- date
- datetime
- enumeration
- bool
fieldType:
type: string
groupName:
type: string
options:
type: array
items:
type: object
required:
- label
- value
properties:
label:
type: string
value:
type: string
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'429':
$ref: '#/components/responses/RateLimited'
servers:
- url: https://fillo.so
/api/v1/manage/integrations/hubspot/pipelines:
get:
tags:
- Integrations
summary: List HubSpot Deal pipelines
operationId: listHubspotPipelines
description: 'Live Deal pipelines and their stages — the two ids a HubSpot Deal workflow needs. Archived pipelines and stages are omitted. Scope: integrations:manage.'
responses:
'200':
description: Deal pipelines and their stages.
content:
application/json:
schema:
type: object
required:
- pipelines
properties:
pipelines:
type: array
items:
type: object
required:
- id
- label
- stages
properties:
id:
type: string
label:
type: string
stages:
type: array
items:
type: object
required:
- id
- label
properties:
id:
type: string
label:
type: string
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'429':
$ref: '#/components/responses/RateLimited'
servers:
- url: https://fillo.so
components:
responses:
NotFound:
description: No such resource in this project (returned instead of 403 for ids in other projects).
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
RateLimited:
description: Per-key (120/min), per-workspace (240/min), or per-IP (300/min) rate limit exceeded. Retry after the Retry-After header.
headers:
RateLimit-Policy:
description: Named quota policies and their limits/windows.
schema:
type: string
RateLimit:
description: Current remaining quota and seconds until reset for each named policy.
schema:
type: string
RateLimit-Limit:
description: 'Compatibility field: effective request limit.'
schema:
type: integer
RateLimit-Remaining:
description: 'Compatibility field: effective requests remaining.'
schema:
type: integer
RateLimit-Reset:
description: 'Compatibility field: seconds until the effective window resets.'
schema:
type: integer
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Forbidden:
description: The key is valid but lacks the required scope.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
PayloadTooLarge:
description: The request body exceeded the 16 KiB management cap.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Unauthorized:
description: Missing, malformed, unknown, revoked, or expired key.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
BadRequest:
description: Invalid request (e.g. a body on a GET/DELETE, or a missing required query parameter).
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Conflict:
description: The request was understood but refused in this state — an unmet precondition, or a confirm value that did not match. Nothing was changed.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
schemas:
ConfirmTarget:
type: object
required:
- confirm
properties:
confirm:
type: string
description: The exact target value this operation names in its description. A boolean true is rejected by the strict schema, so a bare confirmation can never stand in for a typed one.
description: The typed confirmation a destructive (Tier C) operation requires. A mismatch is 409 and changes nothing.
FormIntegration:
type: object
required:
- provider
- enabled
- config
properties:
provider:
type: string
enum:
- google_sheets
- notion
- slack
- hubspot
enabled:
type: boolean
config:
type:
- object
- 'null'
description: 'The provider''s FormIntegrationConfig keys only; null when the form has never used this destination. Sheets: spreadsheetId, spreadsheetUrl, spreadsheetTitle, sheetTab, sheetTabId, columns. Notion: databaseId, databaseUrl, properties, titleFieldId. Slack: slackChannelId, slackChannelLabel, slackChannelIsPrivate, slackTeamId, slackIncludeFieldIds. HubSpot: hubspotPortalId, hubspotEmailFieldId, hubspotMappings, hubspotFormGuid, hubspotFormName, hubspotCreateMarketableContact, hubspotCompany, hubspotDeal.'
Error:
type: object
required:
- error
properties:
error:
type: string
IntegrationConnections:
type: object
required:
- accounts
- selected
- discordServers
properties:
accounts:
type: array
items:
type: object
required:
- id
- provider
- label
- selected
- projectCount
- formDestinationCount
properties:
id:
type: string
provider:
type: string
enum:
- notion
- slack
- hubspot
- discord
label:
type: string
description: The account's display name — also the exact value a removal must confirm with.
selected:
type: boolean
description: True when the key's project currently uses this account.
projectCount:
type: integer
formDestinationCount:
type: integer
selected:
type: object
required:
- notion
- slack
- hubspot
- discord
properties:
notion:
type:
- string
- 'null'
slack:
type:
- string
- 'null'
hubspot:
type:
- string
- 'null'
discord:
type:
- string
- 'null'
description: The account id this project uses for each provider, or null.
discordServers:
type: array
items:
type: object
required:
- id
- guildId
- name
properties:
id:
type: string
guildId:
type: string
name:
type:
- string
- 'null'
parameters:
FormHandle:
name: form
in: path
required: true
description: A form id or slug.
schema:
type: string
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: 'A project secret key (`fsk_…`). Scopes: forms:read, responses:read, respondents:read, responses:export, forms:write, forms:publish, storage:manage, webhooks:manage, settings:manage, integrations:manage, responses:manage, members:manage, workspace:manage, forms:delete, responses:delete, respondents:delete, workspace:delete. A request for a scope the key lacks returns 403 with a stable message naming the scope (e.g. `This key lacks the responses:export scope.`).'
externalDocs:
description: Fillo developer resources
url: https://fillo.so/developers
x-refined-from:
- fillo-so-openapi.json
- fillo-so-openapi.json
x-provenance:
method: harvested
publisher: Fillo
source: https://fillo.so/openapi.json
note: split by refine-openapis from the provider's own published document, verified by fetch (openapi/_original/*.fetch.json);
stamped by stamp-openapi-provenance.py (roadmap#793)