Schema Contracts for Custom No-Code Connectors
Define each connector action in OpenAPI, constrain its request and response bodies with JSON Schema, and preserve released shapes as contracts. Test shared fixtures against the provider and the generated action before every release. If a field is removed, renamed, narrowed, or newly required, publish a new connector version for incompatible flows.
Prerequisites
You need the provider’s current API behavior, access to a safe environment where requests can run, and at least one real request and response for every connector action you plan to expose. Collect the existing connector definition and identify the production flows that already consume it. Without that consumer list, you cannot distinguish an additive edit from a release that strands an old flow.
Keep credentials out of fixtures and the OpenAPI document. The schema describes where authentication data belongs; it is not a place to store values. Set up secret handling for no-code flows before running provider or connector tests. If an action receives callbacks, treat webhook replay protection as a separate protocol requirement rather than trying to express it through the payload schema.
The schema is a release boundary
A connector schema is both a description of the provider and an input to the system that generates actions, fields, and outputs. The OpenAPI 3.2.0 specification, published 19 September 2025, defines a language-independent description for HTTP APIs and explicitly includes generated clients and testing tools among its uses. That makes a released OpenAPI document an interface contract, not an editable mock-up of the visual connector form.
Follow these steps in order:
-
Capture contract fixtures before editing the schema.
For each action, save a representative request body and every response shape the action is expected to handle. A fixture is a concrete payload paired with the schema and operation it is meant to satisfy. It preserves details that are easy to erase while cleaning up a definition: whether a field is absent or present, whether a value is a string or number, and whether a collection is empty or populated.
Start from payloads produced or accepted by the provider rather than examples written from memory. Redact credentials and personal data without changing field names, types, nesting, or collection structure. Keep separate fixtures where the provider legitimately returns different response shapes. A single successful response cannot prove that error or alternate responses still match the connector contract.
Add invalid fixtures for the boundaries you intend the schema to reject: a missing required field, a value with the wrong type, a value that does not match its declared format, and a collection beyond its documented bound. These fixtures explain why each constraint exists. They also stop a later editor from loosening a rule merely because the connector editor will save the document.
This costs maintenance whenever provider behavior changes. It is still cheaper than reconstructing an old payload after a flow fails. Fixtures are the wrong tool only when they are treated as screenshots or documentation samples. They must be machine-readable inputs that can be run against both sides of the contract.
-
Choose the OpenAPI dialect the connector platform actually imports.
Use the newest dialect only when the target connector platform supports it. Otherwise, write the contract in the newest dialect that the importer accepts and validate that document directly. Do not assume that support for OpenAPI as a category means support for every version or every JSON Schema keyword.
The condition is platform support, not preference. For example, the Microsoft Learn custom-connector guide, checked 26 August 2026, says its Power Apps, Power Automate, and Logic Apps import path requires OpenAPI 2.0 and does not support OpenAPI 3.0 definitions. For that import path, OpenAPI 2.0 is the usable choice even though later OpenAPI specifications exist. For a platform that accepts a later dialect, use that supported dialect and its matching schema semantics.
Record the chosen version at the root of the document and configure the schema validator for the same version. A validator using different rules can approve constructs that the connector importer ignores or rejects. Import the document into a disposable connector early, before the full contract has grown around an unsupported feature.
Supporting an older dialect may require a separate connector-facing document from the provider’s newer canonical description. That adds a synchronization cost. Do not solve it by silently deleting constraints during conversion; either preserve the constraint in a supported form or record that the importer cannot express it and cover the gap with fixtures.
-
Define each action’s complete request and response shapes.
Add one operation for each action the no-code user can select. Define its path, method, parameters or request body, and the response bodies the action is expected to expose. Give the operation a stable identifier because generated connector actions and saved flows may refer to that identity even when the visual label changes.
Describe the request and response independently. The provider accepting a field in a request does not mean it returns that field, and a value found in a response does not prove it is accepted as input. Reuse a shared schema only when the two shapes are genuinely the same contract. Convenience is not enough: an input may permit a client-supplied value while the corresponding output is provider-generated or absent.
Define responses rather than asking the connector editor to infer them from one test call. Inference captures the sample that happened to arrive, not the range the provider promises. If two documented responses have different bodies, model both instead of merging their fields into one object in which everything appears optional.
The work here is mostly review time: someone must compare the provider exchange, the fixtures, and the OpenAPI document field by field. The wrong shortcut is to draw the action in the visual editor and export the result as the first authoritative contract. The editor can help generate a starting document, but the reviewed OpenAPI file must remain the source used for validation and release.
-
Apply JSON Schema constraints at the point where values enter or leave.
For every property, declare its type. Mark fields as required at the object that owns them. Apply formats only when the provider contract defines that format. For arrays, define the item shape and encode documented lower or upper bounds with collection constraints. The JSON Schema Draft 2020-12 core specification explains the schema mechanism: keywords assert constraints on JSON instances, while applicators apply schemas to nested objects and arrays.
Use the constraints deliberately:
typeprevents a field that looks plausible in the editor from crossing the boundary in the wrong representation.requireddistinguishes a field that must be present from one the provider permits callers or responses to omit. Put only genuinely mandatory names in that list.formatrecords an expected representation for a string. Because tool support can differ, keep a fixture that violates the format and confirm that the validator and generated connector behave as intended.minItemsandmaxItemsexpress bounded collections. Set their values from the provider’s documented limits or observed contract, not from a convenient test payload. If no verified bound exists, do not invent one.
Apply response constraints with the same care as request constraints. A permissive response schema can let the provider drift until a later flow tries to read a missing or differently typed output. An unjustifiably narrow response schema creates the opposite failure: the provider returns a valid payload that the connector cannot represent.
Constraint work costs time twice: first when the schema is written, and again when a provider change forces a compatibility decision. The wrong answer is maximum strictness without evidence. Do not add a format, required field, or collection maximum simply because the schema language offers the keyword. Every constraint must correspond to provider behavior and a fixture.
-
Classify compatibility before importing an update.
Compare the proposed document with the released schema. Treat removal, renaming, narrowing, and newly required fields as breaking changes even when the visual connector editor accepts the update.
The mechanism differs in each case:
- Removing a request property leaves an existing flow supplying an input the new action no longer describes. Removing a response property leaves downstream steps referring to an output the new action no longer exposes.
- Renaming is removal plus addition. Preserving the meaning of the value does not preserve the field name stored in a flow.
- Narrowing rejects data the old contract allowed. This includes changing a type, reducing an accepted set of values, lowering a collection maximum, or replacing a broad shape with a more restrictive one.
- Making an optional field required creates an obligation that saved flows did not have when they were built. A newly created flow may show the new input correctly while an old flow still lacks it.
Visual-editor acceptance proves only that the editor can store the updated definition. It does not prove that old flow definitions can supply the new request or consume the new response. Review compatibility outside the editor and record the reason for each classification.
An optional additive field is a candidate for an in-place update only after old fixtures and representative flows still pass. If the new field changes how an existing field is interpreted, the change is not harmless merely because the new property is optional.
Maintaining an old contract alongside a new one costs release and support time. Accept that cost when consumers cannot migrate atomically. Mutating the existing action is the wrong answer whenever a saved flow cannot run against the proposed schema without being edited.
-
Run the fixture suite directly against the provider.
Validate each request fixture against the request schema before sending it. Then call the provider in the safe test environment and validate the returned body against the declared response for that operation. Run valid fixtures, invalid fixtures, and the collection boundaries encoded in the schema.
This half of the test separates provider drift from connector-generation defects. If a fixture no longer works directly against the provider, changing the visual action cannot repair the contract. Decide whether the provider changed, the fixture was wrong, or the schema described behavior the provider never guaranteed.
Do not weaken a response schema merely to make an unexplained payload pass. First establish whether that shape is part of the provider contract. If it is, add the shape deliberately and repeat the compatibility review. If it is not verified, keep the release blocked rather than turning uncertainty into a permanent optional field.
Direct tests cost provider calls and require controlled test data. They are the wrong place to exercise destructive production actions. Use a safe provider environment or fixtures tied to operations that can be run without damaging live data. The requirement is to test the provider boundary, not to create avoidable production side effects.
-
Run the same fixtures through the generated connector actions.
Import the exact OpenAPI artifact proposed for release and generate the connector actions from it. For every request fixture, supply the same values through the action and validate its output against the same response schema used in the direct provider test.
This second path tests behavior that a provider-only suite cannot cover: how the connector importer interprets the document and how the generated action presents and transports the declared fields. If the direct provider call passes but the generated action fails, the defect lies in the connector definition, the importer’s supported subset, or the generated action—not in the provider payload.
Include an existing flow for each released action, not only a newly assembled test flow. A new flow proves that the current editor can build against the new schema. An existing flow proves that a stored consumer can still run. Use the same production ownership model planned for release; service-principal ownership of no-code flows avoids making a personal test identity the hidden owner of the contract suite.
Generated-action tests take longer than schema validation and may require a deployed test connector. Do not replace them with the editor’s validation panel. Editor validation checks the definition it understands; it does not run old flows or compare the provider path with the generated-action path.
-
Version the connector when old flows cannot consume the new schema.
Make the version decision from the compatibility review and test results. If old flows cannot send a newly required request, still produce a now-required response, resolve a renamed output, or satisfy a narrowed constraint, release a new connector version. Keep the old contract available for existing flows until those consumers have been migrated or retired.
Version at the boundary the platform exposes: a connector version, a new action identity, or a separate connector definition. The required outcome is that the incompatible schema does not silently replace the contract used by old flows. Publish the OpenAPI document, generated actions, fixtures, and compatibility record as one release so the tested artifacts cannot drift apart.
An in-place update is appropriate only when the old fixtures and representative existing flows pass through the generated actions unchanged. Passing schema lint alone is insufficient. Conversely, do not create a new version merely because the prose description or visual label changed; versioning is for a contract old consumers cannot use.
Supporting two versions costs maintenance and lengthens migration. That is the concrete price of preserving production flows. Set a migration owner and identify every known consumer before retiring the old version. Do not remove it on the assumption that the connector editor would have warned about downstream use.
Expected result
Done means the released OpenAPI document defines every connector action’s request and response shapes, including verified types, required fields, formats, and collection bounds. The same contract fixtures pass directly against the provider and through the generated connector actions. Every removal, rename, narrowing, or newly required field is recorded as breaking, and incompatible flows remain on an older connector version until they are migrated.
Sources
- OpenAPI 3.2.0 specification, published 19 September 2025spec.openapis.org
- Microsoft Learn custom-connector guidelearn.microsoft.com
- JSON Schema Draft 2020-12 core specificationjson-schema.org
See also
Store credentials by reference, keep them out of every output surface, and rotate them without breaking a production no-code automation.
Move a production no-code flow from employee ownership to a service principal, preserve every binding, and prepare rotation and emergency transfer.
Choose signed or unsigned Cloudinary upload presets by client path, parameter control, and the guardrails a public no-code flow can enforce.
How strict transformation allowlists block unknown no-code delivery variants, preserve approved ones, and change the release process.