const url = 'https://platform.fomr.io/v1/forms/example/publish';const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
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/publish \ --header 'Authorization: Bearer <token>'Publishes the stored draft and answers the form resource. A draft identical to the latest published version republishes that version number; any other draft becomes the next version. There are no preconditions: the version number is computed under the form lock, so the last call wins. Publish Validation runs first, and a draft that is not ready is refused with 422 carrying the same Publish Issues validate returns; a draft flagged by automated safety checks is refused with 422 FORM_SAFETY_REJECTED, and a token owner without a verified email with 403 FORM_PUBLISH_EMAIL_UNVERIFIED. A Private Template cannot be published and is refused with 400 INVALID_INPUT at is_template. Needs forms:write and form_publish. 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.
Responses
Section titled “Responses”Default Response
object
The public ID of the form. Use it in every other form call.
Form name shown in the app.
Whether the resource is a Private Template rather than a form.
Lifecycle state: draft while nothing is published, published once a version is live, archived when the form is no longer editable.
Whether publishing would change what respondents see. True for a form that has never been published.
The workspace the form belongs to. Change it with the move operation.
Whether the form takes submissions.
object
Whether the form was closed by hand.
Whether the form takes a submission right now. Derived from is_closed, the schedule, and whether a version is published.
One completed response per respondent IP address.
object
The matching method: ip_address, submission_id, or component.
One completed response per browser, using the completed response ID saved in it.
object
The matching method: ip_address, submission_id, or component.
Rejects a completed response that repeats an earlier answer to one question. Blank optional answers are not checked.
object
The matching method: ip_address, submission_id, or component.
Public ID of the question whose answer must be unique: a visible short text, email, phone, link, or number block on a visible page.
How many submissions the form holds.
object
Submissions the respondent finished.
Partial responses captured before the respondent finished.
object
The custom domain of the share link, such as forms.example.com.
The path after the host, starting with a slash.
Verification state of the domain: verified, pending, or failed.
Whether the plan of the organization keeps the domain serving forms.
The link on the custom domain. It becomes urls.share once the domain is verified and active and a version is published.
When the form was created.
When the form was last changed.
Example
{ "status": "draft", "access": { "duplicate_response_rule": { "type": "ip_address" } }, "domain": { "status": "verified" }}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"}A Plan Error: either an exhausted plan limit or a field that needs a larger plan. Branch on code.
object
The organization is already at a limit its plan sets.
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 plan whose limit was applied.
Where to review plans and upgrade the organization.
The limit that blocked the call.
object
Which plan limit was reached.
What the plan allows.
What the organization is using right now.
object
The request sets a field the plan does not include.
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 plan whose features were applied.
Where to review plans and upgrade the organization.
The plan feature the blocked field needs, such as meta_tags or partial_response_access.
The path of the blocked field, such as properties/meta_title. On a write it points into the request body; on publish it points into the Draft Document, and it is empty when the blocker is not a document field.
Example
{ "code": "PLAN_LIMIT_REACHED", "plan": "free", "limit": { "key": "max_forms" }}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 that does not exist, is in Trash, or belongs to another organization. The three 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 form that cannot be published as it stands: it is archived, or it holds no draft. Branch on code.
object
The form is archived: it has no editable draft, so draft writes, publish, and conversion are refused.
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.
object
The form has no draft version to publish.
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": "FORM_ARCHIVED"}A publish the server refused: the draft has Publish Issues, or safety checks flagged it. Branch on code.
object
The draft is not complete enough to publish. Nothing was written.
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 Publish Issue that blocked the publish. The same list validate returns.
object
The stable Publish Issue code to branch on. Besides the draft checks, validate reports FORM_PUBLISH_EMAIL_UNVERIFIED, FORM_SAFETY_REJECTED, and PRO_FEATURE_REQUIRED for what publish would refuse. New codes are added over time.
What to fix, in words. Not part of the contract; never branch on it.
The path into the Draft Document, with property names and numeric array indexes, such as [“pages”, 1, “nodes”, 0, “meta”, “select_options_data”]. Empty when the issue is about the form as a whole.
object
Automated safety checks flagged the draft. Nothing was published; the form and its owner are held for review.
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": "FORM_PUBLISH_VALIDATION_FAILED", "issues": [ { "code": "FORM_PUBLISH_DRAFT_INVALID" } ]}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"}