Skip to main content
To record a customer’s feedback, you submit a fill of a questionnaire: the profile who answered, what the answers are about, and the answers themselves. Omneo saves the submission, then routes each answer to the destination declared on its question. This guide covers submitting a fill and what happens next. For the model behind it, see Questions and questionnaires. All endpoints are bearer authenticated and live under https://api.[tenant].getomneo.com/api/v3.

Submitting a fill

Post the fill to the questionnaire’s submissions endpoint:
A successful submission returns 201.
FieldTypeNotes
profile_id*uuidThe Profile who filled the form.
answerable*objectWhat the answers are about. See below.
answers*arrayOne entry per answer. See Addressing each answer.
contextobjectOptional resolution hints used when routing needs to find a target, for example transaction_id, transaction_item_id, appointment_id, or connection_id.

The answerable

answerable is the subject of the fill: { "type": ..., "id": ... }. The type names what the answers describe and id identifies the specific record. Common types are profile, transaction, product_variant, and appointment, and many other resource types are accepted.
The answerable frames the whole submission. Individual answers can still route to different destinations based on each question’s link configuration.

Addressing each answer

Each entry in answers carries a value and identifies which question slot it belongs to. You can identify the slot three ways, in order of specificity:
IdentifierUse when
questionnaire_question_idYou have the exact slot id from the questionnaire. Most precise.
question_idYou have the question id but not the slot id.
question_handleYou are working from stable handles, for example a hand-authored front end.
A full submission addressed by handle:
Here the fill is about the Profile, and context.transaction_id tells any transaction-routed answer which transaction to write to. Supply the context key a question needs to resolve its destination: transaction_id, transaction_item_id, appointment_id, or connection_id.

What happens after submission

Routing runs after the submission is saved. Each answer is routed independently against the link configuration on its question, and one answer failing does not affect the others. An answer is saved as pending, then routing moves it to one of three terminal states:
StateMeaning
pendingSaved but not yet routed. Re-read the submission or answer to see the terminal state once routing has run.
mappedThe destination was written.
skippedNothing to write, for example a capture-only question (link_type of none).
failedThe write could not be applied, for example the target could not be resolved.
Because routing is per answer, a fill can partly succeed: a score routes to a Rating while a free-text comment is captured only. For where each link_type writes and the profile write policies, see Routing answers.

The submission response

The 201 response is the observable result of the fill. Its answers[] is not an echo of what you sent: each entry is the routing outcome for one answer, carrying the resolved destination and a mapping_status. This example fills the post-visit form with a score that routes to a Rating and a comment that is captured only:

Top-level fields

FieldNotes
submission_idId of the saved submission.
questionnaire_idThe questionnaire that was filled.
submitted_countNumber of answers accepted.
answerableThe subject of the fill, as { type, id }.
contextThe resolution hints supplied on the request.
submitted_atWhen the fill was recorded.
answersOne routing outcome per answer. See below.

Answer outcome fields

Each entry in answers[] is a routing outcome:
FieldNotes
idThe stored answer id.
questionnaire_question_idThe slot the answer was given for.
question_idThe question id.
question_handleThe question handle.
question_version_idThe question version the answer is pinned to.
profile_idThe Profile who answered.
answerable_typeType of the submission subject.
answerable_idId of the submission subject.
mapping_keyThe slot’s key within the form.
link_typeRouting destination kind, copied from the question.
link_targetDestination within the link_type.
link_write_policyOverwrite policy applied.
question_labelThe label shown at submission time.
question_typeThe input type.
question_requiredWhether the slot was required.
answer_typeData type of the stored value.
valueThe submitted value.
mappable_typeType of the record written. Populated when mapping_status is mapped.
mappable_idId of the record written. Populated when mapping_status is mapped.
mapped_fieldField written on the destination. Populated when mapping_status is mapped.
mapping_statusmapped, skipped, or failed. See below.
mapping_errorReason the write could not be applied. Populated when mapping_status is failed.
mapped_atWhen the write happened. Populated when mapping_status is mapped.
metaFree-form metadata.
created_atWhen the answer was stored.
updated_atWhen the answer last changed.
The values of mapping_status:
mapping_statusMeaningPopulated fields
pendingThe answer is saved but has not been routed yet.None yet.
mappedThe destination was written.mappable_type, mappable_id, mapped_field, mapped_at.
skippedNothing to write, for example a capture-only question (link_type of none).None of the mapping fields.
failedThe write could not be applied.mapping_error.
A saved submission returns 201 even when some answers end in failed. Routing outcomes are reported per answer inside answers[], not as an HTTP error. Read each mapping_status to confirm the writes you expected actually landed.

Routing to a Rating

An answer whose question has link_type of rating always inserts a new Rating rather than updating an earlier one. Re-submitting a score for the same subject creates a second Rating, so the store accumulates every score over time. When you need a single current value, such as a product’s latest NPS from one customer, read the Ratings for that subject and aggregate on the most recent. Do not assume one Rating per subject per customer.

End-to-end example

This walks a single post-visit form from authoring to inspecting its routing outcomes. Authoring detail lives in Building questionnaires; the commands here are condensed to show the whole flow.
1

Create the questions

Author a score that routes to a Rating and a comment that is captured only.
2

Build the questionnaire with a page

Create the form, add a page, then place both slots on that page.
3

Submit a fill

Post the two answers for the Profile who filled the form.
4

Inspect the routing outcomes

Read answers[] in the 201 response. The nps-score answer comes back with mapping_status of mapped and a mappable_type of rating, so a new Rating was written. The visit-comment answer comes back skipped because its link_type is none, so it was captured without a destination. This is the response shown in The submission response.

Edge cases and gotchas

  • The answerable frames the fill, answers still route independently. answerable names the overall subject, but each answer routes to the destination on its own question, which can differ from the answerable. A profile fill can still write a Rating and a Transaction answer at once.
  • Version pinning is permanent. Each stored answer records question_version_id. Editing the question later creates a new version and never rewrites answers already captured, so historical responses stay exact.
  • Reads nest the rendering fields. When you read a question to render a form, its label, type, options, and validation come back under current_version, not at the top level. See The question response shape.
  • Ratings always insert. A rating answer creates a new Rating every time. Re-submitting a score for the same subject accumulates Ratings rather than updating one, so aggregate on the most recent when you need a single current value.
  • A failed answer does not fail the request. The submission is still saved and returns 201. The failure is reported on that answer, with mapping_status of failed and a reason in mapping_error:
A common cause is a missing resolution hint: supply the context key the question needs (transaction_id, transaction_item_id, appointment_id, or connection_id) so the destination can be found.

The booking case

Appointment booking questions are a questionnaire attached to the appointment definition, but their answers are not submitted through the submissions endpoint. Instead, send them inside the appointment create payload, on the answers array, addressed by questionnaire_question_id:
See Working with appointments for the full booking flow. Post-visit feedback and standalone surveys use the submissions endpoint on this page instead, so booking answers stay with the booking and later feedback is captured as its own submission.

Errors

StatusWhen
401The bearer token is missing or invalid.
403The token is valid but lacks the scope or permission to submit.
404The questionnaire does not exist, or a referenced slot is not part of it.
422Validation failed. A submission requires profile_id, answerable, and answers.
A failed routing outcome is not an HTTP error. The submission still returns 201; inspect each answer’s mapping_status to confirm the writes landed.