This guide walks through how to create a connector in the FlowSync API, how each authentication strategy is represented, and what the request payload should look like. It reflects the current server behaviour where:
- Connector routes (except
GET /connectors/search) require an authenticated FlowSync user. - The backend sets
tenant_idandcreated_byfrom the authenticated user; they must not be supplied in the request body. - Incoming payloads are validated against
connector.schema.json.
Endpoint & Authentication#
| Method | Path | Auth | Notes |
|---|---|---|---|
POST |
/api-core/cliodot/connectors |
Bearer (FlowSync JWT) | Creates a connector for the caller’s tenant |
PUT |
/api-core/cliodot/connectors/:connectorId |
Bearer (FlowSync JWT) | Updates an existing connector |
tenant_id and created_by are taken from the JWT (req.flowUser). The API rejects unauthenticated requests and validates payloads with AJV.
Required Top-Level Fields#
| Field | Type | Description |
|---|---|---|
name |
string |
Display name |
type |
REST | SOAP | GRAPHQL | CUSTOM | system |
Protocol classification |
auth |
object |
Authentication configuration (see below) |
For REST connectors: base_url (URI) and endpoints (array, min 1 item) are required.
Optional: _id, slug, description, allowBaseUrlEdit, meta, endpoints[].action, endpoints[].description, endpoints[].headers, endpoints[].params, endpoints[].pathParams, endpoints[].body_schema, endpoints[].response_mapping, endpoints[].timeout_ms, endpoints[].sample_responses.
Meta Object#
When meta is provided, the Mongoose model requires: category, logo, status, visibility_settings (with visibility and public_access), and last_updated. If last_updated is omitted, the API defaults it to the current date.
meta.visibility_settings.visibility governs discoverability:
public,public_private: visible to unauthenticated users (public) and all authenticated users.private: only the creator who authenticated the request can see it.organization,organization_public,organization_private,team: visible to authenticated tenants, matching rules enforced in search and list.
public_access describes allowed public operations (read, write, read_write, none).
Example Payload#
Below is a comprehensive connector payload demonstrating all supported authentication capabilities. Uncomment or tailor the sections you need before sending. Omit the _id field if you want the platform to generate one for you:
{
"_id": "crm-suite-v2",
"name": "CRM Suite",
"slug": "crm-suite",
"type": "REST",
"base_url": "https://api.crm-suite.io/v2",
"auth": {
"type": "oauth2",
"token_url": "https://auth.crm-suite.io/oauth/token",
"client_id": "crm_suite_app",
"client_secret": "crm_suite_secret",
"scopes": ["contacts.read", "contacts.write"],
"flow": {
"method": "POST",
"url": "https://auth.crm-suite.io/oauth/token",
"headers": {
"Content-Type": "application/json"
},
"body": {
"client_id": "{{ auth.client_id }}",
"client_secret": "{{ auth.client_secret }}",
"grant_type": "client_credentials",
"scope": "{{ auth.scopes | join(' ') }}"
},
"extract_token": "access_token",
"extract_expires_in": "expires_in",
"token_template_prefix": "Bearer ",
"token_descriptor": {
"location": "header",
"header_name": "Authorization",
"prefix": "Bearer "
}
},
"custom": {
"X-CRM-Region": "us-central-1"
},
"fallback": {
"type": "api_key",
"name": "X-CRM-API-KEY",
"key": "fallback_YOUR_API_KEY"
}
},
"endpoints": [
{
"name": "List Contacts",
"method": "GET",
"path": "/contacts",
"params": {
"limit": 100,
"page": "{{ vars.page ?? 1 }}"
},
"response_mapping": {
"collection": "data.items",
"next_page": "meta.next_page"
}
},
{
"name": "Create Contact",
"method": "POST",
"path": "/contacts",
"headers": {
"Content-Type": "application/json"
},
"body_schema": {
"first_name": "string",
"last_name": "string",
"email": "string",
"phone": "string"
},
"response_mapping": {
"id": "data.id",
"status": "meta.status"
}
}
],
"meta": {
"category": "CRM",
"logo": "https://cdn.crm-suite.io/logos/primary.png",
"status": "active",
"visibility_settings": {
"visibility": "organization_private",
"public_access": "read"
},
"last_updated": "2025-11-10T10:00:00Z",
"tags": ["crm", "contacts"]
}
}
Alternative Auth Snippets#
Replace the auth block above with one of the examples below, depending on your use case.
Bearer
"auth": {
"type": "bearer",
"token": "YOUR_BEARER_TOKEN",
"header_name": "Authorization",
"custom_headers": {
"X-Env": "sandbox"
}
}
Basic
"auth": {
"type": "basic",
"username": "api_user",
"password": "YOUR_PASSWORD"
}
API Key
"auth": {
"type": "api_key",
"api_key": "YOUR_API_KEY",
"header_name": "X-API-KEY"
}
None
"auth": {
"type": "none"
}
Custom Headers
"auth": {
"type": "custom",
"custom_headers": [
{ "key": "X-CUSTOM-1", "value": "value1" },
{ "key": "X-CUSTOM-2", "value": "value2" }
],
"fallback": {
"type": "basic",
"username": "backup",
"password": "YOUR_BACKUP_PASSWORD"
}
}
Custom with Flow (token exchange)
"auth": {
"type": "custom",
"flow": {
"method": "POST",
"url": "https://auth.example.com/oauth/token",
"headers": { "Content-Type": "application/x-www-form-urlencoded" },
"body": {
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": "{{ auth.assertion }}",
"scope": "{{ auth.scope }}"
},
"extract_token": "access_token",
"extract_expires_in": "expires_in",
"token_location": "header",
"token_template_prefix": "Bearer "
}
}