Skip to content

Testing Connectors

Testing ensures your connector descriptor is valid, credentials work, and operations return expected data. Manifest Platform provides testing at every layer: descriptor validation, connection verification, operation execution, and ongoing health monitoring.


Testing Workflow

graph TD
    V["1. Validate Descriptor"] --> T["2. Test Connection"]
    T --> O["3. Test Operations"]
    O --> SD["Schema Discovery<br/>(optional)"]
    O --> DDL["DDL Execution<br/>(database connectors)"]
    O --> H["4. Monitor Health"]
    H --> HC["On-Demand Health Check"]
    H --> BHC["Bulk Health Check"]

1. Descriptor Validation

Before registering a connector, validate the descriptor to catch structural issues.

Coming Soon

The Python SDK for local development is not yet publicly available.

from flow_sdk.cli_client import CLIClient

client = CLIClient(config)

result = client.connectors.validate(descriptor={
    "metadata": {
        "name": "My API",
        "slug": "my-api",
        "version": "1.0.0",
        "description": "Integration with My API service",
        "publisher": "Team"
    },
    "authentication": [...],
    "operations": [...],
    "capabilities": {"sync_modes": ["full_refresh"]},
    "sla": {"availability_percentage": 99.0}
})

if result.valid:
    print("Descriptor is valid")
    # result.normalized_descriptor contains the cleaned-up version
else:
    for error in result.errors:
        print(f"Error: {error}")

What Validation Checks

Check Description
Required fields All mandatory fields present with correct types
Auth profile uniqueness No duplicate authentication type entries
Operation ID uniqueness Every operation has a unique operation_id
Auth references Each operation's auth_type_ref points to a defined auth profile
MCP mappings MCP route mappings reference existing operations
MCP tool name uniqueness No duplicate tool names in MCP configuration
Field constraints String lengths, regex patterns, numeric ranges

2. Connection Testing

After creating an instance and storing credentials, test the connection:

Coming Soon

The Python SDK for local development is not yet publicly available.

result = client.connector_instances.test_connection(
    instance_id="uuid-of-instance",
    scope_type="organization",
    scope_id="uuid-of-org",
)

print(f"Status: {result.status}")
print(f"Message: {result.message}")
print(f"Details: {result.details}")
print(f"Tested at: {result.tested_at}")

How Connection Testing Works

The test method depends on the authentication type:

Auth Type Test Method
none No credentials required; skips credential validation
api_key Calls the test_endpoint URL with credentials injected into headers
basic Calls the test_endpoint URL with HTTP Basic auth header
service_account Calls the test_endpoint URL with service account credentials
oauth2_client_credentials Performs token exchange and verifies success
oauth2_authorization_code Verifies stored tokens are valid (refreshes if needed)
Credential chain Executes all chain steps in order and verifies the final credential is obtained

Test Result Fields

Field Description
status success, failed, or pending
message Human-readable summary of the result
details Additional diagnostic detail (e.g., raw error from the external API)
tested_at ISO 8601 timestamp of when the test was run
Status Meaning
success Credentials are valid, external system is reachable
failed Authentication failed, system unreachable, or unexpected response
pending Test is in progress (async)

Test after every credential change

Always run a connection test after storing or rotating credentials. A common issue is copying credentials with trailing whitespace or newline characters.


3. Testing Operations

Test individual connector operations to verify they return expected data.

Dataset Source Test

If the connector instance is linked as a dataset source, use the source test endpoint:

Coming Soon

The Python SDK for local development is not yet publicly available.

result = client.datasets.test_source(
    dataset_id="uuid-of-dataset",
    source_id="uuid-of-source",
    parameters={"status": "open"},
    limit=5,
)

if result.success:
    print(f"Returned {result.record_count} rows in {result.execution_time_ms}ms")
    print(f"Inferred schema: {result.response_schema}")
    for row in result.sample_rows:
        print(row)
else:
    print(f"Error: {result.error}")
    print(f"Status code: {result.status_code}")

The test response includes:

Field Description
success Whether the operation completed without errors
status_code HTTP status code from the external API
response_schema Schema inferred from the response data
sample_rows Up to limit rows of data
record_count Total rows returned
error Error message if the operation failed
execution_time_ms How long the operation took

Operation Input Validation

The platform validates operation parameters before execution:

# The platform automatically validates:
# - Required parameters are present
# - Parameter types match the declared field_type
# - Extra parameters are silently ignored

Validation issues return structured errors:

{
  "valid": false,
  "issues": [
    {"path": "jql", "expected": "required", "actual": "missing"},
    {"path": "maxResults", "expected": "integer", "actual": "string"}
  ]
}

Operation Output Validation

If an operation defines a response_schema, the platform validates the external API's response:

  • Top-level type check (object, array, string, etc.)
  • Required property check for object responses
  • Property-level type checks

Output validation failures are logged as warnings but do not block the response. This prevents brittle behavior when external APIs add new fields.


4. Health Monitoring

On-Demand Health Checks

Run a lightweight health check on any instance:

Coming Soon

The Python SDK for local development is not yet publicly available.

health = client.connector_instances.health_check(
    instance_id="uuid-of-instance",
    scope_type="organization",
    scope_id="uuid-of-org",
    timeout_seconds=10.0,
)

print(f"Status: {health.status}")       # healthy or unhealthy
print(f"Latency: {health.latency_ms}ms")
if health.error:
    print(f"Error: {health.error}")

Health Check Result Fields

Field Description
status healthy or unhealthy
latency_ms Round-trip time to the external system in milliseconds
error Error message if the check failed, otherwise null

Bulk Health Checks

Check multiple instances at once:

Coming Soon

The Python SDK for local development is not yet publicly available.

results = client.connector_instances.bulk_operation(
    instance_ids=["uuid-1", "uuid-2", "uuid-3"],
    action="health_check",
)

for r in results:
    status = "OK" if r.status == "success" else "FAIL"
    print(f"  {r.instance_id}: {status}")

Expiring Credentials

Monitor credentials approaching expiration:

Coming Soon

The Python SDK for local development is not yet publicly available.

expiring = client.connector_instances.list_expiring_credentials(
    days_ahead=14,
)

for cred in expiring:
    if cred.days_remaining < 0:
        print(f"EXPIRED: {cred.connector_name} (expired {abs(cred.days_remaining):.0f} days ago)")
    else:
        print(f"EXPIRING: {cred.connector_name} ({cred.days_remaining:.0f} days remaining)")

Debugging Common Issues

Authentication Failures

Symptom Likely Cause Fix
401 Unauthorized Invalid or expired credentials Re-store credentials and test connection
403 Forbidden Credentials lack required permissions Check API scopes/roles on the external system
Connection timeout Network or firewall issue Verify the external system is reachable from the platform
test_endpoint returns unexpected status Wrong test URL or changed API Update the test_endpoint in the connector descriptor

Operation Failures

Symptom Likely Cause Fix
Missing required parameter Parameter not provided in request Check operation parameter definitions
Type mismatch String sent where integer expected Verify field_type in parameter spec matches actual API
Empty response Operation returns no data Verify the query/filter parameters are correct
Rate limit exceeded Too many requests in interval Check rate_limits in descriptor and reduce request frequency

MCP Tool Issues

Symptom Likely Cause Fix
Tool not appearing for agent MCP not enabled on connector Set mcp_config.enabled: true in descriptor
Tool call fails silently Credential scope mismatch Ensure agent has credentials at the correct scope
Stale tool behavior Cached MCP server Update the connector descriptor to invalidate cache

Enable logging for debugging

Connector operations are logged in the platform's observability system. Check the execution traces for detailed request/response data, including headers, status codes, and timing.