const url = 'https://platform.fomr.io/v1/forms/example/workflows?dry_run=true';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"name":"example","nodes":[{"public_id":"example","node_type_key":"form_completed","position":{"x":1,"y":1},"config":{}}],"edges":[{"public_id":"example","source_node_public_id":"example","target_node_public_id":"example","source_handle":"example","target_handle":"example"}]}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url 'https://platform.fomr.io/v1/forms/example/workflows?dry_run=true' \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "name": "example", "nodes": [ { "public_id": "example", "node_type_key": "form_completed", "position": { "x": 1, "y": 1 }, "config": {} } ], "edges": [ { "public_id": "example", "source_node_public_id": "example", "target_node_public_id": "example", "source_handle": "example", "target_handle": "example" } ] }'Creates a workflow on a form from a Workflow Document and answers 201 with the stored document, every minted ID included. The workflow starts disabled; call enableFormWorkflow to run it. The graph passes the same checks as the app builder, and a form holds at most 25 workflows. A google_sheets_add_row node with a config creates its spreadsheet in the connected Google account. Use dry_run=true to validate without writing. Needs forms:write and workflows:write. Costs 1 API credit.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”The public ID of the form or Private Template.
Query Parameters
Section titled “Query Parameters”Validate the document and resolve every ID without writing anything or creating a spreadsheet. Costs the same as a real write and answers 200 with the document the real call would have stored.
Request Body
Section titled “Request Body”A Workflow Document to create or replace a workflow with. The read-only fields of a read document are accepted and ignored.
object
Workflow name, trimmed.
Every node the workflow should have. On replace, a stored node whose ID is left out is removed. A runnable workflow has exactly one form_completed trigger.
Node type form_completed: New response. Runs when a respondent completes this form. Kind: trigger.
object
Optional on write. A present ID keeps the node of this workflow with that ID, or creates a node with that ID when the workflow has none; an absent ID creates a node with a server-minted ID. Node IDs are unique across fomr and never reused, so an ID another workflow or a removed node holds is refused. A chosen ID has at least 8 characters.
Discriminates the node type. A node keeps its type: to change it, replace the node with a new one.
Canvas position of the node in the app workflow builder. It has no effect on how the workflow runs.
object
Horizontal canvas coordinate of the node in the app workflow builder.
Vertical canvas coordinate of the node in the app workflow builder.
Optional and always empty: the trigger has no settings, and the read document leaves the field out.
object
Node type google_sheets_add_row: Sync to Google Sheets. Append a completed response to a spreadsheet. Kind: action.
object
Optional on write. A present ID keeps the node of this workflow with that ID, or creates a node with that ID when the workflow has none; an absent ID creates a node with a server-minted ID. Node IDs are unique across fomr and never reused, so an ID another workflow or a removed node holds is refused. A chosen ID has at least 8 characters.
Discriminates the node type. A node keeps its type: to change it, replace the node with a new one.
Canvas position of the node in the app workflow builder. It has no effect on how the workflow runs.
object
Horizontal canvas coordinate of the node in the app workflow builder.
Vertical canvas coordinate of the node in the app workflow builder.
The Google Sheets destination of the step. Once set, fomr creates the spreadsheet, and the destination cannot change afterwards: replace the node with a new one to use another spreadsheet.
object
The public ID of a connected Google Sheets connection of the organization, as listIntegrationConnections returns it.
Name of the spreadsheet fomr creates in that Google account to receive the completed responses, trimmed.
The spreadsheet fomr created for the step. Read-only.
Every edge the workflow should have. On replace, a stored edge that is not sent is removed.
A connection that runs the target node after the source node.
object
Optional on write. A present ID keeps the edge of this workflow with that ID, or creates an edge with that ID; an absent ID keeps an existing edge between the same nodes and handles, or creates one with a server-minted ID.
The public ID of the node the edge starts from, in the nodes of the same document. Only the trigger can start edges.
The public ID of the node the edge leads to, in the nodes of the same document.
The public ID of the workflow. Ignored on write.
Whether the workflow runs. Ignored on write; use enable and disable.
The result of the last enable check. Ignored on write.
When the workflow was created. Ignored on write.
When the workflow last changed. Ignored on write.
Responses
Section titled “Responses”Default Response
object
Always true. Nothing was written, and minted IDs are not reserved for a later call.
The Workflow Document the real call would have stored.
object
The public ID of the workflow. Use it in the other workflow calls.
Workflow name shown in the Workflows tab of the form.
Whether the workflow runs when a respondent completes the form. Change it with enable and disable.
Unchecked until the workflow is first enabled, valid once it passed the enable checks, invalid when the last check failed.
When the workflow was created.
When the workflow last changed.
The nodes of the workflow graph, oldest first. Issue paths index into this array.
Node type form_completed: New response. Runs when a respondent completes this form. Kind: trigger.
object
The public ID of the node. Edges name their endpoints with it.
Discriminates the node type. A node keeps its type: to change it, replace the node with a new one.
Canvas position of the node in the app workflow builder. It has no effect on how the workflow runs.
object
Horizontal canvas coordinate of the node in the app workflow builder.
Vertical canvas coordinate of the node in the app workflow builder.
Node type google_sheets_add_row: Sync to Google Sheets. Append a completed response to a spreadsheet. Kind: action.
object
The public ID of the node. Edges name their endpoints with it.
Discriminates the node type. A node keeps its type: to change it, replace the node with a new one.
Canvas position of the node in the app workflow builder. It has no effect on how the workflow runs.
object
Horizontal canvas coordinate of the node in the app workflow builder.
Vertical canvas coordinate of the node in the app workflow builder.
The Google Sheets destination of the step. Once set, fomr creates the spreadsheet, and the destination cannot change afterwards: replace the node with a new one to use another spreadsheet.
object
The public ID of a connected Google Sheets connection of the organization, as listIntegrationConnections returns it.
Name of the spreadsheet fomr creates in that Google account to receive the completed responses, trimmed.
The spreadsheet fomr created for the step. Read-only.
The edges of the workflow graph, oldest first. Issue paths index into this array.
A connection that runs the target node after the source node.
object
The public ID of the edge.
The public ID of the node the edge starts from.
The public ID of the node the edge leads to.
Example
{ "dry_run": true, "workflow": { "validation_status": "unchecked", "validation_error_code": "WORKFLOW_VALIDATION_TOO_MANY_WORKFLOWS", "nodes": [ { "node_type_key": "form_completed" } ] }}The Workflow Document: a workflow of a form with its whole graph. Read it, change it, and send it back to replace it.
The Workflow Document: a workflow of a form with its whole graph. Read it, change it, and send it back to replace it.
object
The public ID of the workflow. Use it in the other workflow calls.
Workflow name shown in the Workflows tab of the form.
Whether the workflow runs when a respondent completes the form. Change it with enable and disable.
Unchecked until the workflow is first enabled, valid once it passed the enable checks, invalid when the last check failed.
When the workflow was created.
When the workflow last changed.
The nodes of the workflow graph, oldest first. Issue paths index into this array.
Node type form_completed: New response. Runs when a respondent completes this form. Kind: trigger.
object
The public ID of the node. Edges name their endpoints with it.
Discriminates the node type. A node keeps its type: to change it, replace the node with a new one.
Canvas position of the node in the app workflow builder. It has no effect on how the workflow runs.
object
Horizontal canvas coordinate of the node in the app workflow builder.
Vertical canvas coordinate of the node in the app workflow builder.
Node type google_sheets_add_row: Sync to Google Sheets. Append a completed response to a spreadsheet. Kind: action.
object
The public ID of the node. Edges name their endpoints with it.
Discriminates the node type. A node keeps its type: to change it, replace the node with a new one.
Canvas position of the node in the app workflow builder. It has no effect on how the workflow runs.
object
Horizontal canvas coordinate of the node in the app workflow builder.
Vertical canvas coordinate of the node in the app workflow builder.
The Google Sheets destination of the step. Once set, fomr creates the spreadsheet, and the destination cannot change afterwards: replace the node with a new one to use another spreadsheet.
object
The public ID of a connected Google Sheets connection of the organization, as listIntegrationConnections returns it.
Name of the spreadsheet fomr creates in that Google account to receive the completed responses, trimmed.
The spreadsheet fomr created for the step. Read-only.
The edges of the workflow graph, oldest first. Issue paths index into this array.
A connection that runs the target node after the source node.
object
The public ID of the edge.
The public ID of the node the edge starts from.
The public ID of the node the edge leads to.
Example
{ "validation_status": "unchecked", "validation_error_code": "WORKFLOW_VALIDATION_TOO_MANY_WORKFLOWS", "nodes": [ { "node_type_key": "form_completed" } ]}Default Response
object
The stable code to branch on.
A human-readable explanation. Not part of the contract; never branch on it.
The ID of the failed request, also sent as the X-Request-Id response header.
Every value the request got wrong.
object
The path into the request, with property names and numeric array indexes.
What is wrong with the value at this path.
The stable code for the issue. Branch on it, and use it with params to write your own text.
Accepted values when a node type or enum value is rejected.
Example
{ "code": "INVALID_INPUT"}Default Response
object
The stable code to branch on.
A human-readable explanation. Not part of the contract; never branch on it.
The ID of the failed request, also sent as the X-Request-Id response header.
Example
{ "code": "INVALID_INPUT"}Default Response
object
The stable code to branch on.
A human-readable explanation. Not part of the contract; never branch on it.
The ID of the failed request, also sent as the X-Request-Id response header.
Example
{ "code": "INVALID_INPUT"}Default Response
object
Returned for a form or workflow that does not exist, is in Trash or deleted, belongs to another organization, or for a Private Template, which has no workflows. These cases are not told apart.
A human-readable explanation. Not part of the contract; never branch on it.
The ID of the failed request, also sent as the X-Request-Id response header.
Example
{ "code": "NOT_FOUND"}A rejected call. The organization budget names the policy it rejected the call under; the request floor that bounds hammering sends the envelope alone.
object
The stable code to branch on.
A human-readable explanation. Not part of the contract; never branch on it.
The ID of the failed request, also sent as the X-Request-Id response header.
The policy that rejected the call.
The plan whose numbers were applied.
The policy limit in credits.
Credits already spent in the open window.
Credits still available under the policy.
What the rejected call would have cost.
How long the policy window lasts.
When the window that rejected the call ends.
Seconds to wait before retrying. Also sent as the Retry-After response header.
object
The stable code to branch on.
A human-readable explanation. Not part of the contract; never branch on it.
The ID of the failed request, also sent as the X-Request-Id response header.
Example
{ "code": "INVALID_INPUT", "policy": "minute", "plan": "free"}Default Response
object
The stable code to branch on.
A human-readable explanation. Not part of the contract; never branch on it.
The ID of the failed request, also sent as the X-Request-Id response header.
Example
{ "code": "INVALID_INPUT"}Default Response
object
The requested operation has no available capacity. Retry after the Retry-After header says.
A human-readable explanation. Not part of the contract; never branch on it.
The ID of the failed request, also sent as the X-Request-Id response header.
Seconds to wait before retrying. Also sent as the Retry-After response header.
Example
{ "code": "SERVICE_UNAVAILABLE"}