Edit a question of a draft

PATCH /supplier-assessment-templates/{templateId}/questions/{questionId}

Scope supplier_template:write Plan Growth+

Change fields of one question of a draft: text, help, evidenceHint (each replaces the whole localised object), answerType, required, modes, domain, weight, controlIds and allowNotApplicable. At least one field is required. The question’s id, its options and its gating rules are not editable here (use the option operations for options). A field edit is lock-free: it does not check or change the draft revision (a revision or If-Match sent with it is ignored), and an edit that changes nothing returns 200 and is not recorded. The edit does not re-check the whole questionnaire (for example a choice question needs two options): run validateSupplierTemplate, which submit also runs. Only a draft can be edited: published, archived and submitted versions answer 409 (TEMPLATE_PUBLISHED, TEMPLATE_ARCHIVED, TEMPLATE_SUBMITTED). Field edit: 120 per token and hour. Requires the supplier_template:write scope (or a signed-in Owner, Manager or Contributor session).

Example

curl -X PATCH "https://api.autociso.io/api/v1/supplier-assessment-templates/<templateId>/questions/<questionId>" \
  -H "Authorization: Bearer <your-api-token>" \
  -H "Content-Type: application/json" \
  -d '{"weight":8,"required":true}'

Response 200

{
  "data": {
    "templateId": "satpl_1hgyun41rx48",
    "templateKey": "tpl_1hgyun41rx49",
    "version": 0,
    "titleKey": "",
    "title": {
      "en": "Example vendor security review"
    },
    "modes": [],
    "source": "authored",
    "status": "draft",
    "active": false,
    "questionCount": 1,
    "revision": 4,
    "createdAt": "2026-10-09T08:15:00Z",
    "updatedAt": "2026-10-09T08:20:00Z",
    "sections": [
      {
        "sectionId": "sect_1hgyun41rx4a",
        "titleKey": "",
        "title": {
          "en": "Governance"
        },
        "order": 1,
        "questions": [
          {
            "questionId": "saq_1hgyun41rx4d",
            "textKey": "",
            "text": {
              "en": "Is data encrypted at rest?"
            },
            "answerType": "single_select",
            "required": true,
            "modes": [],
            "domain": "operations",
            "weight": 8,
            "authored": true,
            "options": [
              {
                "optionId": "saqo_1hgyun41rx4e",
                "labelKey": "",
                "label": {
                  "en": "Yes, all stores"
                },
                "riskValue": 0
              },
              {
                "optionId": "saqo_1hgyun41rx4f",
                "labelKey": "",
                "label": {
                  "en": "No"
                },
                "riskValue": 4,
                "findingSeverity": "high"
              }
            ]
          }
        ]
      }
    ],
    "limits": {
      "maxSections": 20,
      "maxQuestionsPerSection": 50,
      "maxQuestionsPerTemplate": 300,
      "maxOptionsPerQuestion": 12
    },
    "permissions": {
      "canEdit": true,
      "canSubmit": true,
      "canWithdraw": false,
      "canReject": false,
      "canPublish": false,
      "canSetDefault": false,
      "canArchive": false,
      "canDelete": true,
      "publishBlockedReason": null
    }
  }
}

Path parameters

  • templateId string required
    Questionnaire document id (satpl_...), or satpl_builtin_supplier_security_privacy_v1 for the built-in one.
  • questionId string required
    Question id, as returned in sections[].questions[].questionId.

Header parameters

  • If-Match string
    The draft revision as W/"<revision>", from the ETag header. Wins over a revision in the body. A write on an older revision fails with 409 STALE_REVISION. pattern ^W/"[0-9]+"$

Request body

  • text object
    Text per locale. en is required; ru and he fall back to en when blank. At most 500 characters per locale (2000 for a description); HTML is rejected.
    • en string required
      minLength 1, maxLength 500
    • ru string
      maxLength 500
    • he string
      maxLength 500
  • help object
    Text per locale, at most 2000 characters per locale; HTML is rejected. All locales are optional.
    • en string
      maxLength 2000
    • ru string
      maxLength 2000
    • he string
      maxLength 2000
    • No other fields.
  • evidenceHint object
    Text per locale, at most 2000 characters per locale; HTML is rejected. All locales are optional.
    • en string
      maxLength 2000
    • ru string
      maxLength 2000
    • he string
      maxLength 2000
    • No other fields.
  • answerType string
    "text" | "email" | "phone" | "textarea" | "single_select" | "multi_select"
  • required boolean
  • modes array of string
  • domain string
    "" | "governance" | "privacy" | "access" | "operations" | "resilience" | "supply_chain" | "contractual"
  • weight integer
    Scoring weight. minimum 1, maximum 10
  • controlIds array of string
  • allowNotApplicable boolean
  • revision integer
    Accepted and ignored: a field edit does not check the revision. minimum 0
  • No other fields.

Returns

The data field of the standard { data, error, meta } envelope:

  • templateId string required
  • templateKey string required
    Shared by all versions of the questionnaire.
  • version integer required
    0 for an open draft.
  • titleKey string required
  • descriptionKey string
  • title object
    Text per locale. en is required; ru and he fall back to en when blank. At most 500 characters per locale (2000 for a description); HTML is rejected.
    • en string required
      minLength 1, maxLength 500
    • ru string
      maxLength 500
    • he string
      maxLength 500
  • description object
    Text per locale. en is required; ru and he fall back to en when blank. At most 500 characters per locale (2000 for a description); HTML is rejected.
    • en string required
      minLength 1, maxLength 500
    • ru string
      maxLength 500
    • he string
      maxLength 500
  • modes array of string required
  • source string
    "builtin" | "authored"
  • status string
    draft and submitted are open (editable or awaiting approval); published is the live version; archived is retired.
    "draft" | "submitted" | "published" | "archived"
  • active boolean required
  • isDefault boolean
  • questionCount integer
  • revision integer
    Send with an edit; changes on every structural edit.
  • contentHash string
  • clonedFromKey string
  • clonedFromVersion integer
  • parentVersion integer
  • publishedAt string (date-time)
  • publishedBy string
  • createdAt string (date-time) required
  • updatedAt string (date-time) required
  • createdBy string
  • updatedBy string
  • lastEditedBy string
  • lastEditedAt string (date-time)
  • submittedBy string
  • submittedAt string (date-time)
  • submitterNote string
  • rejectedBy string
  • rejectedAt string (date-time)
  • rejectionReason string
  • sections array of object required
    • sectionId string required
    • titleKey string required
    • title object
      Text per locale. en is required; ru and he fall back to en when blank. At most 500 characters per locale (2000 for a description); HTML is rejected.
      Show 3 propertiesHide 3 properties { en, ru, he }
      • en string required
        minLength 1, maxLength 500
      • ru string
        maxLength 500
      • he string
        maxLength 500
    • order integer required
    • questions array of object required
      Show 19 propertiesHide 19 properties { questionId, textKey, helpKey, answerType, … }
      • questionId string required
      • textKey string required
        Built-in text key; authored questions carry text instead.
      • helpKey string
      • answerType string required
        "text" | "email" | "phone" | "textarea" | "single_select" | "multi_select"
      • required boolean required
      • modes array of string required
      • domain string required
        "" | "governance" | "privacy" | "access" | "operations" | "resilience" | "supply_chain" | "contractual"
      • syncTarget string
      • evidenceHintKey string
      • options array of object
        Show 8 propertiesHide 8 properties { optionId, labelKey, notApplicable, label, … }
        • optionId string required
        • labelKey string required
          Built-in text key; authored options carry label instead.
        • notApplicable boolean
        • label object
          Text per locale. en is required; ru and he fall back to en when blank. At most 500 characters per locale (2000 for a description); HTML is rejected.
          Show 3 propertiesHide 3 properties { en, ru, he }
          • en string required
            minLength 1, maxLength 500
          • ru string
            maxLength 500
          • he string
            maxLength 500
        • riskValue integer
          Scoring: 0 (no risk) to 4. minimum 0, maximum 4
        • findingSeverity string
          "info" | "low" | "medium" | "high" | "critical"
        • findingKey string
        • finding object
          Text per locale. en is required; ru and he fall back to en when blank. At most 500 characters per locale (2000 for a description); HTML is rejected.
          Show 3 propertiesHide 3 properties { en, ru, he }
          • en string required
            minLength 1, maxLength 500
          • ru string
            maxLength 500
          • he string
            maxLength 500
      • requiresVendorTypes array of string
      • allowNotApplicable boolean
      • requiresResponses array of object
        Show 2 propertiesHide 2 properties { questionId, anyOption }
        • questionId string required
        • anyOption array of string required
      • text object
        Text per locale. en is required; ru and he fall back to en when blank. At most 500 characters per locale (2000 for a description); HTML is rejected.
        Show 3 propertiesHide 3 properties { en, ru, he }
        • en string required
          minLength 1, maxLength 500
        • ru string
          maxLength 500
        • he string
          maxLength 500
      • help object
        Text per locale. en is required; ru and he fall back to en when blank. At most 500 characters per locale (2000 for a description); HTML is rejected.
        Show 3 propertiesHide 3 properties { en, ru, he }
        • en string required
          minLength 1, maxLength 500
        • ru string
          maxLength 500
        • he string
          maxLength 500
      • evidenceHint object
        Text per locale. en is required; ru and he fall back to en when blank. At most 500 characters per locale (2000 for a description); HTML is rejected.
        Show 3 propertiesHide 3 properties { en, ru, he }
        • en string required
          minLength 1, maxLength 500
        • ru string
          maxLength 500
        • he string
          maxLength 500
      • authored boolean
      • weight integer
        Scoring weight. minimum 1, maximum 10
      • controlIds array of string
  • limits object required
    The structural caps the server enforces.
    • maxSections integer required
      maximum 20
    • maxQuestionsPerSection integer required
      maximum 50
    • maxQuestionsPerTemplate integer required
      maximum 300
    • maxOptionsPerQuestion integer required
      maximum 12
  • permissions object
    What the caller may do with this version right now.
    • canEdit boolean required
    • canSubmit boolean required
    • canWithdraw boolean required
    • canReject boolean required
    • canPublish boolean or null required
    • canSetDefault boolean required
    • canArchive boolean required
    • canDelete boolean required
    • publishBlockedReason string or null required

Errors

Status Code Retry Meaning
400 VALIDATION_FAILED no The JSON body does not match the request schema, or the revision is missing where required. code VALIDATION_FAILED.
401 INVALID_TOKEN no Missing (UNAUTHORIZED) or invalid, expired or revoked (INVALID_TOKEN) token.
402 FEATURE_GATED no The tenant plan does not include supply chain security. code FEATURE_GATED; args.feature, args.minTier, args.minTierName.
403 INSUFFICIENT_SCOPE no The token lacks supplier_template:write (INSUFFICIENT_SCOPE), has no accountable person (FORBIDDEN: this principal cannot edit questionnaires), or the target is the built-in questionnaire (BUILTIN_IMMUTABLE).
404 NOT_FOUND no Unknown questionnaire, question or option in the path. code NOT_FOUND.
409 TEMPLATE_SUBMITTED no The version cannot take this edit. code TEMPLATE_PUBLISHED, TEMPLATE_SUBMITTED or TEMPLATE_ARCHIVED (not a draft; args.current holds the document).
413 PAYLOAD_TOO_LARGE no The JSON body exceeds the size limit. code PAYLOAD_TOO_LARGE.
429 RATE_LIMITED yes Too many failed authentication attempts from this address, or the token used its hourly write budget (30 structural, 120 field edits). code RATE_LIMITED; wait Retry-After seconds, also in error.args.retryAfterSeconds.
500 DB_ERROR no Unexpected server error. code DB_ERROR; quote error.id to support.
503 BILLING_UNAVAILABLE yes Billing is temporarily unavailable, so the plan could not be checked. code BILLING_UNAVAILABLE. Retry later.
Last reviewed: 2026-10-13

Was this page helpful?

Esc