Use cases Yandex Forms API
This section walks you through Python scripts and show you how to use the Yandex Forms API for managing forms and user responses.
All examples use an OAuth token for authentication. Learn how to issue tokens in the API access section.
1. Publishing and unpublishing an existing form
You may want to publish a form via the API when publishing it requires more complex logic than the default options available in Yandex Forms (publishing by time, unpublishing when a certain number of responses is reached, and others).
example_1.py script
import os
import requests
import sys
FORMS_PUBLIC_API = 'https://api.forms.yandex.net/v1'
FORMS_OAUTH_TOKEN = os.environ.get('FORMS_OAUTH_TOKEN')
def publish_survey(survey_id: str) -> bool:
"""
Publish the form.
The form won't be published if:
- The form is blocked.
- The form has already received the maximum number of user responses.
- Auto-publishing is enabled and the publication time hasn't yet arrived.
"""
url = f'{FORMS_PUBLIC_API}/surveys/{survey_id}/publish'
headers = {'Authorization': f'OAuth {FORMS_OAUTH_TOKEN}'}
response = requests.post(url, headers=headers)
return response.status_code == 200
def unpublish_survey(survey_id: str) -> bool:
"""
You can unpublish any form, including if automatic publication is enabled and the specified unpublishing time hasn't arrived.
"""
url = f'{FORMS_PUBLIC_API}/surveys/{survey_id}/unpublish'
headers = {'Authorization': f'OAuth {FORMS_OAUTH_TOKEN}'}
response = requests.post(url, headers=headers)
return response.status_code == 200
def main():
if len(sys.argv) < 2:
return
survey_id = sys.argv[1]
if publish_survey(survey_id):
print(f'Form {survey_id} published')
# if unpublish_survey(survey_id):
# print(f'Form {survey_id} unpublished')
if __name__ == '__main__':
main()
Example of running the script:
$ FORMS_OAUTH_TOKEN=$(cat .user-token) python example_1.py 6800cd9202848f10b272a9cc
Form 6800cd9202848f10b272a9cc published
2. Completing a form using a script
Yandex Forms API allows anonymous users to submit forms (without an OAuth token) unless this setting is disabled (the Show form only to authorized users option in the form settings).
To submit a form on behalf of a specific user, you must make the request with an OAuth token.
Form field values (answers to questions) are passed in JSON format as question ID–value pairs.
example_2.py script
import json
import os
import requests
import sys
FORMS_PUBLIC_API = 'https://api.forms.yandex.net/v1'
FORMS_OAUTH_TOKEN = os.environ.get('FORMS_OAUTH_TOKEN')
def submit_survey(survey_id: str, **fields) -> int:
"""
"""
url = f'{FORMS_PUBLIC_API}/surveys/{survey_id}/form'
headers = {'Authorization': f'OAuth {FORMS_OAUTH_TOKEN}'}
response = requests.post(url, json=fields, headers=headers)
if response.status_code == 200:
result = response.json()
return result.get('answer_id')
def main():
if len(sys.argv) < 3:
return
survey_id = sys.argv[1]
fields = json.loads(sys.argv[2])
answer_id = submit_survey(survey_id, **fields)
if answer_id:
print(f'Form {survey_id} filled out and response {answer_id} created')
if __name__ == '__main__':
main()
Example of running the script:
$ FORMS_OAUTH_TOKEN=$(cat .user-token) python example_2.py 6800cd9202848f10b272a9cc '
{
"id-text": "test it",
"id-bool": true,
"id-integer": 42,
"id-enum": ["id-second", "id-third"]
}
'
Form 6800cd9202848f10b272a9cc filled out and response 2037950340 created
3. Getting a form response
Let's look at an example of retrieving a form response by its ID.
Response data is returned in JSON format. If needed, you can process it with Python or the jq command-line utility, or convert it to CSV format.
example_3.py script
import json
import os
import requests
import sys
FORMS_PUBLIC_API = 'https://api.forms.yandex.net/v1'
FORMS_OAUTH_TOKEN = os.environ.get('FORMS_OAUTH_TOKEN')
def get_one_answer(answer_id: int):
"""
"""
url = f'{FORMS_PUBLIC_API}/answers'
headers = {'Authorization': f'OAuth {FORMS_OAUTH_TOKEN}'}
fields = {'answer_id': answer_id}
response = requests.get(url, fields, headers=headers)
if response.status_code == 200:
return response.json()
def main():
if len(sys.argv) < 2 or not sys.argv[1].isdigit():
return
answer_id = int(sys.argv[1])
answer_data = get_one_answer(answer_id)
if answer_data:
survey_id = answer_data['survey']['id']
print(f'Received the contents of response {answer_id} to form {survey_id}', file=sys.stderr)
print(json.dumps(answer_data, indent=2, ensure_ascii=False))
if __name__ == '__main__':
main()
Example of running the script using the jq utility:
$ FORMS_OAUTH_TOKEN=$(cat .user-token) python example_3.py 2037950340 \
| jq '.data[] | [.id, .value | if type == "array" then [.[].label] | join(", ") else . end] | @csv'
Received the contents of response 2037950340 to form 6800cd9202848f10b272a9cc
"\"id-text\",\"test it\""
"\"id-bool\",true"
"\"id-integer\",42"
"\"id-enum\",\"Second, Third\""
4. Paginated export of form responses
Yandex Forms API allows you to retrieve form responses in JSON format with paginated access to the results.
The script in the example below processes the responses to generate a CSV-compatible output.
example_4.py script
import csv
import os
import requests
import sys
FORMS_PUBLIC_API_HOST = 'https://api.forms.yandex.net'
FORMS_OAUTH_TOKEN = os.environ.get('FORMS_OAUTH_TOKEN')
def get_value(item):
value = item.get('value')
if value is None:
return ''
if isinstance(value, list):
return ', '.join(value)
return value
def fetch_answers(survey_id: str, *, page_size: int = 50):
"""
"""
headers = {'Authorization': f'OAuth {FORMS_OAUTH_TOKEN}'}
path = f'/v1/surveys/{survey_id}/answers?page_size={page_size}'
columns = None
while True:
url = f'{FORMS_PUBLIC_API_HOST}{path}'
response = requests.get(url, headers=headers)
if response.status_code != 200:
break
result = response.json()
if columns is None:
columns = result.get('columns') or []
yield ['ID', 'Created'] + [
column.get('text')
for column in columns
]
for answer in result.get('answers') or []:
yield [answer.get('id'), answer.get('created')] + [
get_value(item)
for item in answer.get('data') or []
]
next_page = result.get('next')
if not next_page:
break
path = next_page.get('next_url')
if not path:
break
def main():
if len(sys.argv) < 2:
return
survey_id = sys.argv[1]
print(f'Responses to form {survey_id}', file=sys.stderr)
csvwriter = csv.writer(sys.stdout, delimiter=',', quotechar='"', quoting=csv.QUOTE_ALL)
for answer in fetch_answers(survey_id):
csvwriter.writerow(answer)
if __name__ == '__main__':
main()
Example of running the script:
$ FORMS_OAUTH_TOKEN=$(cat .user-token) python example_4.py 6800cd9202848f10b272a9cc
Responses to form 6800cd9202848f10b272a9cc
"ID","Created","Short Text","Boolean","Integer","Enumeration"
"2037950340","2025-04-17T11:30:17Z","test it","True","42","Second, Third"
"2037859858","2025-04-17T10:14:01Z","test it","True","42","Second"
5. Exporting all form responses to a file
To export responses to a file, we'll use several Yandex Forms API calls.
example_5.py script
import json
import os
import requests
import sys
import time
FORMS_PUBLIC_API = 'https://api.forms.yandex.net/v1'
FORMS_OAUTH_TOKEN = os.environ.get('FORMS_OAUTH_TOKEN')
def start_export(survey_id: str) -> str:
"""
Exports responses in background mode.
Returns the code of the running operation.
"""
url = f'{FORMS_PUBLIC_API}/surveys/{survey_id}/answers/export'
headers = {'Authorization': f'OAuth {FORMS_OAUTH_TOKEN}'}
params = {'format': 'xlsx'}
response = requests.post(url, json=params, headers=headers)
if response.status_code == 202:
result = response.json()
operation_id = result.get('id')
return operation_id
print(response.status_code, response.json())
def check_finished(operation_id: str) -> bool:
url = f'{FORMS_PUBLIC_API}/operations/{operation_id}'
headers = {'Authorization': f'OAuth {FORMS_OAUTH_TOKEN}'}
response = requests.get(url, headers=headers)
if response.status_code == 200:
result = response.json()
return result.get('status') == 'ok'
def download_result(survey_id: str, operation_id: str) -> bytes:
url = f'{FORMS_PUBLIC_API}/surveys/{survey_id}/answers/export-results'
headers = {'Authorization': f'OAuth {FORMS_OAUTH_TOKEN}'}
params = {'task_id': operation_id}
response = requests.get(url, params=params, headers=headers)
if response.status_code == 200:
return response.content
def main():
if len(sys.argv) < 2:
return
survey_id = sys.argv[1]
operation_id = start_export(survey_id)
if operation_id:
print(f'Operation {operation_id} started')
while not check_finished(operation_id):
print('...')
time.sleep(5)
content = download_result(survey_id, operation_id)
if content:
filename = f'{survey_id}.xlsx'
with open(filename, 'wb') as f:
f.write(content)
print(f'Downloaded responses to file {filename}')
if __name__ == '__main__':
main()
Example of running the script:
$ FORMS_OAUTH_TOKEN=$(cat .user-token) python example_5.py 6800cd9202848f10b272a9cc
Operation 0946779c-6a57-4070-b062-5d7ebdb65142 started
Downloaded responses to file 6800cd9202848f10b272a9cc.xlsx
6. Uploading and getting files
The script in the example below uploads the file to the form and returns a link that can be used to complete File fields, as shown in the example 2. Completing a form using a script.
We recommend that you set up an external storage for files added to the form responses (see Saving files from responses to the storage):
- For personal forms, set up file storage on Yandex Disk.
- If you use Yandex Forms for Business, use S3 storage in Yandex Cloud.
example_6.py script
import os
import requests
import sys
from pathlib import Path
FORMS_PUBLIC_API = 'https://api.forms.yandex.net/v1'
FORMS_OAUTH_TOKEN = os.environ.get('FORMS_OAUTH_TOKEN')
def upload_file(survey_id: str, filename: Path) -> str:
"""
Upload the file. The result is a link that's used when the form is submitted
"""
url = f'{FORMS_PUBLIC_API}/surveys/{survey_id}/files'
headers = {'Authorization': f'OAuth {FORMS_OAUTH_TOKEN}'}
with open(filename, 'rb') as f:
files = [
('file', (filename.name, f.read(), 'application/octet-stream')),
]
response = requests.post(url, files=files, headers=headers)
if response.status_code == 201:
result = response.json()
return result.get('path')
def download_file(filepath: str) -> bytes:
"""
Download the file
"""
url = f'{FORMS_PUBLIC_API}/files'
headers = {'Authorization': f'OAuth {FORMS_OAUTH_TOKEN}'}
params = {'path': filepath}
response = requests.get(url, params=params, headers=headers)
if response.status_code == 200:
return response.content
def main():
if len(sys.argv) < 3:
return
survey_id = sys.argv[1]
filename = Path(sys.argv[2])
uploaded_path = upload_file(survey_id, filename.expanduser())
print(f'Path to the uploaded file {uploaded_path}')
content = download_file(uploaded_path)
print(content)
if __name__ == '__main__':
main()
Example of running the script:
$ echo 'Hello world' > hello.txt
$ FORMS_OAUTH_TOKEN=$(cat .user-token) python example_6.py 6800cd9202848f10b272a9cc hello.txt
Path to the uploaded file /25871573/6800cd9202848f10b272a9cc/68061a8e381ea60011e104b3_hello.txt
b'Hello world\n'