Create Survey Template

URL

Required Values

HTTP Methods

https://app.tingting.io/api/v1/survey-templates/

name, voice, content

POST

Creates a new survey template. Supports both multipart/form-data (for file uploads) and application/json.

Step Object fields (inside content ):

Field

Type

Required

Description

order

integer (>= 0)

Yes

Step execution order. Must be unique within a template.

content_type

string

Yes

One of: say, play, info

response_type

string

No

One of: dtmf, raw_record, none

input_name

string (max 128)

No

Variable name to store the response. Falls back to field_name.

field_name

string (max 128)

No

Alias for input_name. Used if input_name is absent.

audio_file

string or null

No

Absolute URL (downloaded by server) or local file upload.

Scenario A — JSON body, no audio files

Sample Input:

{
  "name": "Simple DTMF Survey",
  "voice": { "voice_internal_name": "np_rijan" },
  "length_factor": "1.00",
  "content": [
    {
      "order": 0,
      "content_type": "say",
      "response_type": "dtmf",
      "input_name": "rating"
    },
    {
      "order": 1,
      "content_type": "info",
      "response_type": "none",
      "input_name": "outro"
    }
  ]
}

Sample Response (201 Created):

{
  "id": 3,
  "name": "Simple DTMF Survey",
  "voice": {
    "id": 5,
    "voice_display_name": "Rijan",
    "voice_internal_name": "np_rijan",
    "is_premium": false,
    "is_beta": false
  },
  "length_factor": "1.00",
  "content": [
    {
      "order": 0,
      "content_type": "say",
      "response_type": "dtmf",
      "input_name": "rating",
      "audio_file": null
    },
    {
      "order": 1,
      "content_type": "info",
      "response_type": "none",
      "input_name": "outro",
      "audio_file": null
    }
  ],
  "created_at": "2026-06-02T12:00:00Z"
}

Scenario B — Multipart form with uploaded audio files

Audio file field name conventions (higher priority wins for the same step):

Priority

Field name

Description

High

step_<order>_audio_file

<order> is the step’s order value

Medium

content[<i>][audio_file]

<i> is the 0-based index in the array

Low

step_<i>_audio_file

<i> is the 0-based array index

Sample Request (multipart/form-data):

POST /api/v1/survey-templates/
Content-Type: multipart/form-data
Authorization: Token <token>

name=Voice Survey
voice={"voice_internal_name":"np_rijan"}
length_factor=1.2
content=[{"order":0,"content_type":"play","response_type":"raw_record","input_name":"feedback"}]
step_0_audio_file=<binary MP3 file>

Sample Response (201 Created):

{
  "id": 4,
  "name": "Voice Survey",
  "voice": {
    "id": 5,
    "voice_display_name": "Rijan",
    "voice_internal_name": "np_rijan",
    "is_premium": false,
    "is_beta": false
  },
  "length_factor": "1.20",
  "content": [
    {
      "order": 0,
      "content_type": "play",
      "response_type": "raw_record",
      "input_name": "feedback",
      "audio_file": "https://example.com/media/survey_templates/audio/step_0_9f3e21ab.mp3"
    }
  ],
  "created_at": "2026-06-02T12:05:00Z"
}

Scenario C — JSON body with audio file URL (server downloads it)

Sample Input:

{
  "name": "Pre-recorded Survey",
  "voice": { "voice_internal_name": "np_rijan" },
  "content": [
    {
      "order": 0,
      "content_type": "play",
      "response_type": "dtmf",
      "input_name": "choice",
      "audio_file": "https://cdn.example.com/audio/intro.mp3"
    }
  ]
}

The server downloads the provided URL, stores the file, and returns an absolute media URL in the response.

Error Responses (400 Bad Request):

Missing voice on create:

{ "voice": "Voice is required." }

Voice language mismatch:

{
  "voice": "This voice belongs to the 'si' language but your account language is 'np'. Please select a voice that matches your language."
}

Invalid content structure:

{
  "content": [
    "Step 0 (order=0): content_type must be one of: ['say', 'play', 'info']",
    "Step 1 (order=1): duplicate order"
  ]
}