Public API
Token-scoped endpoints used by the public form on /r/{token}.
These endpoints are unauthenticated — possession of the token is the
authorisation. They power the public form at /r/{token} and can also be
called directly if you want to render your own UI on top of Dataopi.
GET /api/public/templates/{token}
Returns the survey definition together with the metadata baked into this template and any existing response.
curl https://your-host/api/public/templates/0c63a3f5-…{
"survey": {
"id": "…",
"name": "Acme CSAT",
"description": "…",
"questions": [/* discriminated-union question objects */],
"theme": { "primaryColor": "teal", "logoUrl": "…", "brandName": "Acme" },
"status": "PUBLISHED"
},
"template": {
"token": "0c63a3f5-…",
"metadata": { "email": "ada@example.com" }
},
"response": {
"answers": [/* present if already submitted, otherwise null */],
"updatedAt": "2026-04-29T10:23:00.000Z"
}
}POST /api/public/templates/{token}/respond
Submits the answers for the first time. Returns 409 if the template has
already been redeemed — use PATCH to edit instead.
curl -X POST https://your-host/api/public/templates/0c63a3f5-…/respond \
-H "Content-Type: application/json" \
-d '{
"answers": [
{ "questionId": "nps", "value": 9 },
{ "questionId": "comments", "value": "Loved the new packaging." }
]
}'The server validates each answer against the question schema (type, required,
min/max, allowed select values, etc.) and rejects the whole submission if any
answer fails.
PATCH /api/public/templates/{token}/respond
Same payload shape as POST. Replaces the previous answers in full — there is
no partial merge. Allowed only while the survey remains PUBLISHED.