curl -X PATCH 'https://verification.didit.me/v3/questionnaires/11111111-2222-3333-4444-555555555555/' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"title": "Updated Customer Onboarding"}'import requests
resp = requests.patch(
f"https://verification.didit.me/v3/questionnaires/{questionnaire_uuid}/",
headers={"x-api-key": "YOUR_API_KEY"},
json={"title": "Updated Customer Onboarding"},
timeout=10,
)
resp.raise_for_status()
print(resp.json()["questionnaire_id"], resp.json()["status"])const res = await fetch(`https://verification.didit.me/v3/questionnaires/${questionnaireUuid}/`, {
method: "PATCH",
headers: {
'x-api-key': 'YOUR_API_KEY',
"Content-Type": "application/json",
},
body: JSON.stringify({ title: "Updated Customer Onboarding" }),
});
if (!res.ok) throw new Error(`Didit ${res.status}`);
const q = await res.json();
console.log(q.questionnaire_id, q.status);<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://verification.didit.me/v3/questionnaires/{questionnaire_uuid}/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'title' => 'Updated Customer Onboarding'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://verification.didit.me/v3/questionnaires/{questionnaire_uuid}/"
payload := strings.NewReader("{\n \"title\": \"Updated Customer Onboarding\"\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://verification.didit.me/v3/questionnaires/{questionnaire_uuid}/")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"title\": \"Updated Customer Onboarding\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://verification.didit.me/v3/questionnaires/{questionnaire_uuid}/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"title\": \"Updated Customer Onboarding\"\n}"
response = http.request(request)
puts response.read_body{
"questionnaire_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"title": "<string>",
"description": "<string>",
"languages": [
"<string>"
],
"default_language": "<string>",
"is_active": true,
"is_simple_questionnaire": true,
"graph": {},
"sections": [
{}
],
"questionnaire_group_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"version": 123,
"status": "draft",
"published_at": "2023-11-07T05:31:56Z",
"is_editable": true
}{
"detail": "You do not have permission to perform this action."
}Update Questionnaire
Update a questionnaire. Versioning depends on the status field you send and the current state of the version: (1) no status on a published version → the published version is updated in place (same questionnaire_id, same version); (2) no status on a draft → the draft is updated and immediately published; (3) status: "published" on a published version → a NEW published version is created under the same questionnaire_group_id (new questionnaire_id, version + 1) and returned, and any existing draft in the group is deleted; (4) status: "draft" keeps a draft as a draft (autosave) but is rejected with 400 on a published version ("Cannot revert a published version to draft.").
curl -X PATCH 'https://verification.didit.me/v3/questionnaires/11111111-2222-3333-4444-555555555555/' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"title": "Updated Customer Onboarding"}'import requests
resp = requests.patch(
f"https://verification.didit.me/v3/questionnaires/{questionnaire_uuid}/",
headers={"x-api-key": "YOUR_API_KEY"},
json={"title": "Updated Customer Onboarding"},
timeout=10,
)
resp.raise_for_status()
print(resp.json()["questionnaire_id"], resp.json()["status"])const res = await fetch(`https://verification.didit.me/v3/questionnaires/${questionnaireUuid}/`, {
method: "PATCH",
headers: {
'x-api-key': 'YOUR_API_KEY',
"Content-Type": "application/json",
},
body: JSON.stringify({ title: "Updated Customer Onboarding" }),
});
if (!res.ok) throw new Error(`Didit ${res.status}`);
const q = await res.json();
console.log(q.questionnaire_id, q.status);<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://verification.didit.me/v3/questionnaires/{questionnaire_uuid}/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'title' => 'Updated Customer Onboarding'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://verification.didit.me/v3/questionnaires/{questionnaire_uuid}/"
payload := strings.NewReader("{\n \"title\": \"Updated Customer Onboarding\"\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://verification.didit.me/v3/questionnaires/{questionnaire_uuid}/")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"title\": \"Updated Customer Onboarding\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://verification.didit.me/v3/questionnaires/{questionnaire_uuid}/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"title\": \"Updated Customer Onboarding\"\n}"
response = http.request(request)
puts response.read_body{
"questionnaire_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"title": "<string>",
"description": "<string>",
"languages": [
"<string>"
],
"default_language": "<string>",
"is_active": true,
"is_simple_questionnaire": true,
"graph": {},
"sections": [
{}
],
"questionnaire_group_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"version": 123,
"status": "draft",
"published_at": "2023-11-07T05:31:56Z",
"is_editable": true
}{
"detail": "You do not have permission to perform this action."
}PATCH for partial updates. To rename a questionnaire, send only title or description.
{
"title": "Updated Customer Onboarding"
}
form_elements array. This replaces the previous question list. Keep any existing questions you still want to show.
{
"form_elements": [
{
"id": "occupation",
"element_type": "short_text",
"label": { "en": "What is your occupation?" },
"is_required": true
},
{
"id": "source_of_funds",
"element_type": "multiple_choice",
"label": { "en": "Source of funds" },
"options": [
{ "value": "employment", "label": { "en": "Employment" } },
{ "value": "business", "label": { "en": "Business" } }
]
}
]
}
graph, branches, next, and conditional rules.
The response includes questionnaire_id. When you update a published questionnaire, the API may create a new version. Capture the returned questionnaire_id and use it in workflows instead of assuming the id in the URL is still the latest version.Authorizations
Path Parameters
Per-version UUID of the questionnaire to update.
Body
Update questionnaire metadata or replace the full linear form_elements list.
Response
Questionnaire updated. The body is the latest state of the resulting version — the in-place updated version, or the newly created published version when you sent status: "published" on a published row (in that case questionnaire_id and version differ from the ones you patched). questionnaire_id in the response is the per-version UUID; use questionnaire_group_id if you need the stable group identifier.
Full questionnaire detail returned from GET, POST (create) and PATCH (update) endpoints.
Unique identifier of the questionnaire. Use this id when referencing the questionnaire from a workflow or in subsequent update/delete requests.
Graph structure with start_node and nodes map.
Questionnaire content grouped into sections (derived from the graph).
Stable identifier that groups all versions of the same questionnaire.
draft, published True when the questionnaire can still be edited in place (draft versions).