Create responses

Answers a published form.

POST /v1/form/public/{id}/responses

Addresshttps://api.hanzo.ai/v1/form/public/{id}/responses
MethodPOST
Operationsubmit_form_response
AuthAuthorization: Bearer $HANZO_API_KEY

Answers a published form. No credential is needed.

The answers are read against the form's own fields: each names a field (by ref) once and carries the one value its type takes, inside its bounds; a completed submission answers every required field. Hidden values are the names the form declares. The response is from the signed-in person when there is one (their account, from their token, never from the body), else from the email field's answer, else from the page's visitor id.

Idempotent by token: the same token is the same response, so a submission sent twice files one. With completed false the answers so far are saved and the response stays open; a completed response is final and a later submission under its token is answered with it unchanged. A subscribe form's response is keyed by its address instead: one address is one subscriber.

A completed response goes to the form's sinks: the event stream, the CRM, the forwarding address, the welcome mail and the webhooks.

429 past the platform's rate for one address, 413 past its body bound, 400 for a body that does not decode, a field no person fills, or any problem with the answers (every one named), 404 for a form that is not published.

Request

18 fields, body application/json (required).

FieldInTypeRequiredDescription
idpathstringyesID is the form's public id, from the path.
answersbodyform.Answer[]—Answers are the answers, one per field at most.
answers[].booleanbodyboolean—
answers[].choicesbodystring[]—
answers[].datebodystring—
answers[].fieldbodystring—Field is the ref of the field answered.
answers[].numberbodynumber (double)—
answers[].textbodystring—
answers[].typebodystring—Type is the field's type.
completedbodyboolean—Completed is false to save the answers so far and keep the response open (a later submission under the same token completes it); true or absent submits it whole, every required field answered.
hiddenbodyobject—Hidden are the values the page passes in, by the names the form declares; each one line of at most 500 characters.
hidden.*bodystring—
idbodystring—ID is the form's public id, from the path.
landed_atbodystring—LandedAt is when the respondent opened the form, RFC 3339.
pathbodystring—Path is the page the form was answered on, at most 500 characters.
tokenbodystring—Token is the client's idempotency token for this response: 8 to 64 letters, digits, dashes and underscores.
visitorbodystring—Visitor is the page's visitor id: letters, digits, dot, dash and underscore, at most 64.
websitebodystring—Website is a field no person sees and no person fills: a submission that fills it is refused.

Response

StatusBodyMeaning
201form.Receiptcreated
defaultproblem-detailsrefused

201 body — 8 fields.

FieldInTypeAlwaysDescription
completedbodyboolean—Completed is whether the response is now submitted whole.
idbodystring—ID is the response's id.
submitted_atbodystring—SubmittedAt is when it was completed, RFC 3339.
thanksbodyform.Screen—
thanks.buttonbodystring—Button is the button's label.
thanks.descriptionbodystring—Description is the text under it.
thanks.redirectbodystring—Redirect is where a thank-you screen sends the respondent instead of showing itself: an https address.
thanks.titlebodystring—Title is the screen's heading.

Failure carries the platform error shape — see Errors.

Examples

hanzo form public responses <id>
import { Configuration, FormApi } from 'hanzoai';

const api = new FormApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.submitFormResponse({ id: 'id', answers: [{"boolean":false,"choices":["<choices>"],"date":"<date>","field":"<field>"}], completed: false });
from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import FormApi

client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = FormApi(client).submit_form_response(id='id', answers=[{"boolean":false,"choices":["<choices>"],"date":"<date>","field":"<field>"}], completed=False)
cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)

resp, _, err := client.FormAPI.SubmitFormResponse(context.Background()).Execute()
if err != nil {
	return err
}
use hanzo_client::apis::{configuration::Configuration, form_api};

let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();

let result = form_api::submit_form_response(&cfg, Default::default()).await?;
import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.FormApi;

ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));

var result = new FormApi(client).submitFormResponse();

The method above is the one at the current release of the document. [email protected] (npm) and [email protected] (PyPI) were generated from an earlier release, where this operation carried a different id, so it spells the method differently — regenerating the clients is what makes the two agree. SDKs →

curl -X POST https://api.hanzo.ai/v1/form/public/<id>/responses \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
       "answers": [
         {
           "boolean": false,
           "choices": [
             "<choices>"
           ],
           "date": "<date>",
           "field": "<field>"
         }
       ],
       "completed": false
     }'

Tool form, op submit_form_response — POST the JSON-RPC envelope to https://api.hanzo.ai/v1/mcp.

curl -X POST https://api.hanzo.ai/v1/mcp \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
       "jsonrpc": "2.0",
       "id": 1,
       "method": "tools/call",
       "params": {
         "name": "form",
         "arguments": {
           "op": "submit_form_response",
           "input": {
             "id": "<id>",
             "answers": [
               {
                 "boolean": false,
                 "choices": [
                   "<choices>"
                 ],
                 "date": "<date>",
                 "field": "<field>"
               }
             ],
             "completed": false
           }
         }
       }
     }'

Form API · All Hanzo APIs · Interactive reference

Was this page useful?
Broken link or missing step? Drop it in #docs on Discord or open a PR.