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.

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: Send exactly one of the three per answer. Sending none, or more than one, returns 422.
mapping_key is not one of these identifiers. It names the slot inside the form for conditions, and it is returned on each answer, but a submission cannot address an answer by it. See Slot keys.
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: 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

Answer outcome fields

Each entry in answers[] is a routing outcome: The values of mapping_status:
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

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.