Forms SDK¶
Examples use a client built as forms = FormsClient(oauth_token="…", organization_id="…").
FormsClient ¶
FormsClient(*, oauth_token: str, organization_id: str, http: HTTPConfig | None = None, transport: BaseTransport | None = None, before_send: BeforeSend | None = None)
Bases: DomainClient
Holds the per-resource forms clients, all sharing one httpx2 core session.
Examples:
>>> forms.me.get().email
'ann@example.com'
me¶
MeClient ¶
MeClient(*, session: SyncSession)
Bases: Resource
The authenticated Forms user.
get ¶
get() -> User
GET /users/me → the authenticated User (a safe auth probe).
Returns:
| Type | Description |
|---|---|
User
|
The authenticated user. |
Examples:
>>> forms.me.get().email
'ann@example.com'
surveys¶
SurveysClient ¶
SurveysClient(*, session: SyncSession)
Bases: Resource
List, get, create, modify, delete, publish and unpublish forms.
list ¶
list(*, limit: int | None = None, name: str | None = None, published: bool | None = None, ownership: str | None = None, group: str | None = None, favourite: bool | None = None, show_all: bool = False, orderby: str | None = None) -> ItemList[Survey]
GET /surveys → every form, page by page, at most limit (None = all).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
limit
|
int | None
|
The most forms to return; |
None
|
name
|
str | None
|
Keep the forms whose name matches. |
None
|
published
|
bool | None
|
Keep only published ( |
None
|
ownership
|
str | None
|
|
None
|
group
|
str | None
|
Keep the forms of this group. |
None
|
favourite
|
bool | None
|
Keep only favourite ( |
None
|
show_all
|
bool
|
For an administrator, list every form of the organization. |
False
|
orderby
|
str | None
|
The sort, a comma list such as |
None
|
Returns:
| Type | Description |
|---|---|
ItemList[Survey]
|
The forms. |
Examples:
>>> forms.surveys.list(limit=500).root[0].name
'Onboarding'
get ¶
get(survey_id: str) -> Survey
GET /surveys/{id} → a single Survey (settings).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
Returns:
| Type | Description |
|---|---|
Survey
|
The form's settings. |
Examples:
>>> forms.surveys.get("686d0a1b2c3d4e5f00000001").name
'Onboarding'
create ¶
create(body: dict[str, Any]) -> Survey
POST /surveys — create a form from a ready body (a dumped SurveyCreate).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
body
|
dict[str, Any]
|
The dumped |
required |
Returns:
| Type | Description |
|---|---|
Survey
|
The created form, with its |
Examples:
>>> forms.surveys.create({"name": "Onboarding", "language": "en"}).id
'686d0a1b2c3d4e5f00000001'
modify ¶
modify(survey_id: str, body: dict[str, Any]) -> Survey
PATCH /surveys/{id} — only the keys present in body change (a SurveyUpdate).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
body
|
dict[str, Any]
|
The keys to change. |
required |
Returns:
| Type | Description |
|---|---|
Survey
|
The updated form. |
Examples:
>>> forms.surveys.modify("686d0a1b2c3d4e5f00000002", {"name": "Onboarding"}).name
'Onboarding'
delete ¶
delete(survey_id: str) -> Ack
DELETE /surveys/{id} (204 No Content) → an :class:Ack.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
Returns:
| Type | Description |
|---|---|
Ack
|
An acknowledgement naming the deleted form. |
Examples:
>>> forms.surveys.delete("686d0a1b2c3d4e5f00000003").ok
True
publish ¶
publish(survey_id: str) -> Ack
POST /surveys/{id}/publish → an :class:Ack.
Fails (typed YandexError) if the form is blocked, has hit its response cap, or is
inside an unexpired response-period window.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
Returns:
| Type | Description |
|---|---|
Ack
|
An acknowledgement naming the published form. |
Examples:
>>> forms.surveys.publish("686d0a1b2c3d4e5f00000004").detail
'published survey 686d0a1b2c3d4e5f00000004'
unpublish ¶
unpublish(survey_id: str) -> Ack
POST /surveys/{id}/unpublish → an :class:Ack (auto-publication forms included).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
Returns:
| Type | Description |
|---|---|
Ack
|
An acknowledgement naming the unpublished form. |
Examples:
>>> forms.surveys.unpublish("686d0a1b2c3d4e5f00000005").detail
'unpublished survey 686d0a1b2c3d4e5f00000005'
questions¶
QuestionsClient ¶
QuestionsClient(*, session: SyncSession)
Bases: Resource
Get, list, create, modify, delete and move the questions of a form.
get ¶
get(survey_id: str, question_id: str, *, with_slugs: bool = False) -> Question
GET /surveys/{id}/questions/{question_id} → a single :class:Question (settings).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
question_id
|
str
|
The question's id. |
required |
with_slugs
|
bool
|
The API's flag of that name: refer to other questions by slug. |
False
|
Returns:
| Type | Description |
|---|---|
Question
|
The question. |
Examples:
>>> forms.questions.get("686d0a1b2c3d4e5f00000010", "17").slug
'name'
list ¶
list(survey_id: str) -> QuestionsResponse
GET /surveys/{id}/questions → every question, grouped into the {pages} envelope.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
Returns:
| Type | Description |
|---|---|
QuestionsResponse
|
Every question, grouped by page. |
Examples:
>>> forms.questions.list("686d0a1b2c3d4e5f00000010").pages[0].items[0].slug
'name'
create ¶
create(survey_id: str, body: QuestionCreate) -> Question
POST /surveys/{id}/questions — append a question from a typed body.
body is one member of the :data:~ycli.yandex.forms.questions.models.QuestionCreate
union (StringQuestion, EnumQuestion, …). The question lands at the end of the
form; reorder it with :meth:move.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
body
|
QuestionCreate
|
The new question's settings. |
required |
Returns:
| Type | Description |
|---|---|
Question
|
The created question, with its |
Examples:
>>> from ycli.yandex.forms.questions.models import StringQuestion
>>> forms.questions.create("686d0a1b2c3d4e5f00000010", StringQuestion(label="Name")).id
17
modify ¶
modify(survey_id: str, question_id: str, body: QuestionCreate) -> Question
PATCH /surveys/{id}/questions/{question_id} — replace a question's settings.
Takes the same typed body as :meth:create; its type must match the existing question.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
question_id
|
str
|
The question's id. |
required |
body
|
QuestionCreate
|
The question's new settings. |
required |
Returns:
| Type | Description |
|---|---|
Question
|
The updated question. |
Examples:
>>> from ycli.yandex.forms.questions.models import StringQuestion
>>> forms.questions.modify(
... "686d0a1b2c3d4e5f00000010", "22", StringQuestion(label="Name")
... ).label
'Name'
delete ¶
delete(survey_id: str, question_id: str, *, force: bool = False) -> Ack
DELETE /surveys/{id}/questions/{question_id} → an :class:Ack.
The API refuses to delete a question that another question's display conditions still
reference (400 dependency_error.question_condition): delete the condition first.
force is sent, and the API ignores it (checked live on 2026-10-04).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
question_id
|
str
|
The question's id. |
required |
force
|
bool
|
Ignored by the API: the display-conditions check is not skipped. |
False
|
Returns:
| Type | Description |
|---|---|
Ack
|
An acknowledgement naming the deleted question. |
Examples:
>>> forms.questions.delete("686d0a1b2c3d4e5f00000010", "28").ok
True
move ¶
move(survey_id: str, question_id: str, body: QuestionMove) -> QuestionMoveResult
POST /surveys/{id}/questions/{question_id}/move — reposition a question.
body names the target page (page / page_id / create_page) and
position; the API ignores a bare position, so QuestionMove refuses one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
question_id
|
str
|
The question's id. |
required |
body
|
QuestionMove
|
The target page and position. |
required |
Returns:
| Type | Description |
|---|---|
QuestionMoveResult
|
The result, carrying the moved question's |
Examples:
>>> from ycli.yandex.forms.questions.models import QuestionMove
>>> forms.questions.move(
... "686d0a1b2c3d4e5f00000010", "20", QuestionMove(page_id=55, position=2)
... ).id
20
conditions¶
ConditionsClient ¶
ConditionsClient(*, session: SyncSession)
Bases: Resource
List, get, create, modify, delete and re-join the display-condition groups of a target.
question_list ¶
question_list(survey_id: str, question_id: str) -> ConditionsResponse
GET /surveys/{id}/questions/{question_id}/conditions → {operator, items}.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
question_id
|
str
|
The question's id. |
required |
Returns:
| Type | Description |
|---|---|
ConditionsResponse
|
The target's operator and condition groups. |
Examples:
>>> forms.conditions.question_list("686d0a1b2c3d4e5f00000090", "17").operator
'or'
question_get ¶
question_get(survey_id: str, question_id: str, condition_id: int) -> Condition
GET …/questions/{question_id}/conditions/{condition_id} → one group.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
question_id
|
str
|
The question's id. |
required |
condition_id
|
int
|
The condition group's id. |
required |
Returns:
| Type | Description |
|---|---|
Condition
|
The condition group. |
Examples:
>>> forms.conditions.question_get("686d0a1b2c3d4e5f00000090", "17", 102).id
102
question_create ¶
question_create(survey_id: str, question_id: str, body: ConditionCreate) -> Condition
POST …/questions/{question_id}/conditions — add a group → it, with its id.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
question_id
|
str
|
The question's id. |
required |
body
|
ConditionCreate
|
The new group: its operator and clauses. |
required |
Returns:
| Type | Description |
|---|---|
Condition
|
The created group, with its |
Examples:
>>> from ycli.yandex.forms.conditions.models import ConditionCreate, ConditionItemWrite
>>> body = ConditionCreate(
... operator="and",
... items=[
... ConditionItemWrite(
... type="question", condition="gt", question="age100", value="18"
... )
... ],
... )
>>> forms.conditions.question_create("686d0a1b2c3d4e5f00000090", "17", body).id
103
question_modify ¶
question_modify(survey_id: str, question_id: str, condition_id: int, body: ConditionUpdate) -> Condition
PATCH …/questions/{question_id}/conditions/{condition_id} — replace the group.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
question_id
|
str
|
The question's id. |
required |
condition_id
|
int
|
The condition group's id. |
required |
body
|
ConditionUpdate
|
The full replacement group: its operator and clauses. |
required |
Returns:
| Type | Description |
|---|---|
Condition
|
The replaced group. |
Examples:
>>> from ycli.yandex.forms.conditions.models import ConditionItemWrite, ConditionUpdate
>>> body = ConditionUpdate(
... operator="or",
... items=[ConditionItemWrite(type="language", condition="eq", value="ru")],
... )
>>> forms.conditions.question_modify("686d0a1b2c3d4e5f00000090", "17", 104, body).id
104
question_delete ¶
question_delete(survey_id: str, question_id: str, condition_id: int) -> None
DELETE …/questions/{question_id}/conditions/{condition_id} (200, no body).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
question_id
|
str
|
The question's id. |
required |
condition_id
|
int
|
The condition group's id. |
required |
Examples:
>>> forms.conditions.question_delete("686d0a1b2c3d4e5f00000090", "17", 106)
question_set_operator ¶
question_set_operator(survey_id: str, question_id: str, operator: ConditionOperatorType) -> ConditionsResponse
PATCH …/questions/{question_id}/conditions — the operator BETWEEN groups.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
question_id
|
str
|
The question's id. |
required |
operator
|
ConditionOperatorType
|
The operator joining the groups: |
required |
Returns:
| Type | Description |
|---|---|
ConditionsResponse
|
The target's operator and condition groups. |
Examples:
>>> forms.conditions.question_set_operator(
... "686d0a1b2c3d4e5f00000090", "17", "or"
... ).operator
'or'
page_list ¶
page_list(survey_id: str, page_id: int) -> ConditionsResponse
GET /surveys/{id}/pages/{page_id}/conditions → {operator, items}.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
page_id
|
int
|
The page's id. |
required |
Returns:
| Type | Description |
|---|---|
ConditionsResponse
|
The target's operator and condition groups. |
Examples:
>>> forms.conditions.page_list("686d0a1b2c3d4e5f00000090", 3).operator
'or'
page_get ¶
page_get(survey_id: str, page_id: int, condition_id: int) -> Condition
GET …/pages/{page_id}/conditions/{condition_id} → one group.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
page_id
|
int
|
The page's id. |
required |
condition_id
|
int
|
The condition group's id. |
required |
Returns:
| Type | Description |
|---|---|
Condition
|
The condition group. |
Examples:
>>> forms.conditions.page_get("686d0a1b2c3d4e5f00000090", 3, 202).id
202
page_create ¶
page_create(survey_id: str, page_id: int, body: ConditionCreate) -> Condition
POST …/pages/{page_id}/conditions — add a group → it, with its id.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
page_id
|
int
|
The page's id. |
required |
body
|
ConditionCreate
|
The new group: its operator and clauses. |
required |
Returns:
| Type | Description |
|---|---|
Condition
|
The created group, with its |
Examples:
>>> from ycli.yandex.forms.conditions.models import ConditionCreate, ConditionItemWrite
>>> body = ConditionCreate(
... operator="and",
... items=[
... ConditionItemWrite(
... type="question", condition="gt", question="age200", value="18"
... )
... ],
... )
>>> forms.conditions.page_create("686d0a1b2c3d4e5f00000090", 3, body).id
203
page_modify ¶
page_modify(survey_id: str, page_id: int, condition_id: int, body: ConditionUpdate) -> Condition
PATCH …/pages/{page_id}/conditions/{condition_id} — replace the group.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
page_id
|
int
|
The page's id. |
required |
condition_id
|
int
|
The condition group's id. |
required |
body
|
ConditionUpdate
|
The full replacement group: its operator and clauses. |
required |
Returns:
| Type | Description |
|---|---|
Condition
|
The replaced group. |
Examples:
>>> from ycli.yandex.forms.conditions.models import ConditionItemWrite, ConditionUpdate
>>> body = ConditionUpdate(
... operator="or",
... items=[ConditionItemWrite(type="language", condition="eq", value="ru")],
... )
>>> forms.conditions.page_modify("686d0a1b2c3d4e5f00000090", 3, 204, body).id
204
page_delete ¶
page_delete(survey_id: str, page_id: int, condition_id: int) -> None
DELETE …/pages/{page_id}/conditions/{condition_id} (200, no body).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
page_id
|
int
|
The page's id. |
required |
condition_id
|
int
|
The condition group's id. |
required |
Examples:
>>> forms.conditions.page_delete("686d0a1b2c3d4e5f00000090", 3, 206)
page_set_operator ¶
page_set_operator(survey_id: str, page_id: int, operator: ConditionOperatorType) -> ConditionsResponse
PATCH …/pages/{page_id}/conditions — the operator BETWEEN groups.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
page_id
|
int
|
The page's id. |
required |
operator
|
ConditionOperatorType
|
The operator joining the groups: |
required |
Returns:
| Type | Description |
|---|---|
ConditionsResponse
|
The target's operator and condition groups. |
Examples:
>>> forms.conditions.page_set_operator("686d0a1b2c3d4e5f00000090", 3, "or").operator
'or'
submit_list ¶
submit_list(survey_id: str) -> ConditionsResponse
GET /surveys/{id}/conditions → {operator, items}.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
Returns:
| Type | Description |
|---|---|
ConditionsResponse
|
The target's operator and condition groups. |
Examples:
>>> forms.conditions.submit_list("686d0a1b2c3d4e5f00000090").operator
'or'
submit_get ¶
submit_get(survey_id: str, condition_id: int) -> Condition
GET /surveys/{id}/conditions/{condition_id} → one group.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
condition_id
|
int
|
The condition group's id. |
required |
Returns:
| Type | Description |
|---|---|
Condition
|
The condition group. |
Examples:
>>> forms.conditions.submit_get("686d0a1b2c3d4e5f00000090", 302).id
302
submit_create ¶
submit_create(survey_id: str, body: ConditionCreate) -> Condition
POST /surveys/{id}/conditions — add a group → it, with its id.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
body
|
ConditionCreate
|
The new group: its operator and clauses. |
required |
Returns:
| Type | Description |
|---|---|
Condition
|
The created group, with its |
Examples:
>>> from ycli.yandex.forms.conditions.models import ConditionCreate, ConditionItemWrite
>>> body = ConditionCreate(
... operator="and",
... items=[
... ConditionItemWrite(
... type="question", condition="gt", question="age300", value="18"
... )
... ],
... )
>>> forms.conditions.submit_create("686d0a1b2c3d4e5f00000090", body).id
303
submit_modify ¶
submit_modify(survey_id: str, condition_id: int, body: ConditionUpdate) -> Condition
PATCH /surveys/{id}/conditions/{condition_id} — replace the group.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
condition_id
|
int
|
The condition group's id. |
required |
body
|
ConditionUpdate
|
The full replacement group: its operator and clauses. |
required |
Returns:
| Type | Description |
|---|---|
Condition
|
The replaced group. |
Examples:
>>> from ycli.yandex.forms.conditions.models import ConditionItemWrite, ConditionUpdate
>>> body = ConditionUpdate(
... operator="or",
... items=[ConditionItemWrite(type="language", condition="eq", value="ru")],
... )
>>> forms.conditions.submit_modify("686d0a1b2c3d4e5f00000090", 304, body).id
304
submit_delete ¶
submit_delete(survey_id: str, condition_id: int) -> None
DELETE /surveys/{id}/conditions/{condition_id} (200, no body).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
condition_id
|
int
|
The condition group's id. |
required |
Examples:
>>> forms.conditions.submit_delete("686d0a1b2c3d4e5f00000090", 306)
submit_set_operator ¶
submit_set_operator(survey_id: str, operator: ConditionOperatorType) -> ConditionsResponse
PATCH /surveys/{id}/conditions — the operator BETWEEN groups.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
operator
|
ConditionOperatorType
|
The operator joining the groups: |
required |
Returns:
| Type | Description |
|---|---|
ConditionsResponse
|
The target's operator and condition groups. |
Examples:
>>> forms.conditions.submit_set_operator("686d0a1b2c3d4e5f00000090", "or").operator
'or'
hook_list ¶
hook_list(survey_id: str, hook_id: int) -> ConditionsResponse
GET /surveys/{id}/hooks/{hook_id}/conditions → {operator, items}.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
hook_id
|
int
|
The integration group's (hook's) id. |
required |
Returns:
| Type | Description |
|---|---|
ConditionsResponse
|
The target's operator and condition groups. |
Examples:
>>> forms.conditions.hook_list("686d0a1b2c3d4e5f00000090", 11).operator
'or'
hook_get ¶
hook_get(survey_id: str, hook_id: int, condition_id: int) -> Condition
GET …/hooks/{hook_id}/conditions/{condition_id} → one group.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
hook_id
|
int
|
The integration group's (hook's) id. |
required |
condition_id
|
int
|
The condition group's id. |
required |
Returns:
| Type | Description |
|---|---|
Condition
|
The condition group. |
Examples:
>>> forms.conditions.hook_get("686d0a1b2c3d4e5f00000090", 11, 402).id
402
hook_create ¶
hook_create(survey_id: str, hook_id: int, body: ConditionCreate) -> Condition
POST …/hooks/{hook_id}/conditions — add a group → it, with its id.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
hook_id
|
int
|
The integration group's (hook's) id. |
required |
body
|
ConditionCreate
|
The new group: its operator and clauses. |
required |
Returns:
| Type | Description |
|---|---|
Condition
|
The created group, with its |
Examples:
>>> from ycli.yandex.forms.conditions.models import ConditionCreate, ConditionItemWrite
>>> body = ConditionCreate(
... operator="and",
... items=[
... ConditionItemWrite(
... type="question", condition="gt", question="age400", value="18"
... )
... ],
... )
>>> forms.conditions.hook_create("686d0a1b2c3d4e5f00000090", 11, body).id
403
hook_modify ¶
hook_modify(survey_id: str, hook_id: int, condition_id: int, body: ConditionUpdate) -> Condition
PATCH …/hooks/{hook_id}/conditions/{condition_id} — replace the group.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
hook_id
|
int
|
The integration group's (hook's) id. |
required |
condition_id
|
int
|
The condition group's id. |
required |
body
|
ConditionUpdate
|
The full replacement group: its operator and clauses. |
required |
Returns:
| Type | Description |
|---|---|
Condition
|
The replaced group. |
Examples:
>>> from ycli.yandex.forms.conditions.models import ConditionItemWrite, ConditionUpdate
>>> body = ConditionUpdate(
... operator="or",
... items=[ConditionItemWrite(type="language", condition="eq", value="ru")],
... )
>>> forms.conditions.hook_modify("686d0a1b2c3d4e5f00000090", 11, 404, body).id
404
hook_delete ¶
hook_delete(survey_id: str, hook_id: int, condition_id: int) -> None
DELETE …/hooks/{hook_id}/conditions/{condition_id} (200, no body).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
hook_id
|
int
|
The integration group's (hook's) id. |
required |
condition_id
|
int
|
The condition group's id. |
required |
Examples:
>>> forms.conditions.hook_delete("686d0a1b2c3d4e5f00000090", 11, 406)
hook_set_operator ¶
hook_set_operator(survey_id: str, hook_id: int, operator: ConditionOperatorType) -> ConditionsResponse
PATCH …/hooks/{hook_id}/conditions — the operator BETWEEN groups.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
hook_id
|
int
|
The integration group's (hook's) id. |
required |
operator
|
ConditionOperatorType
|
The operator joining the groups: |
required |
Returns:
| Type | Description |
|---|---|
ConditionsResponse
|
The target's operator and condition groups. |
Examples:
>>> forms.conditions.hook_set_operator("686d0a1b2c3d4e5f00000090", 11, "or").operator
'or'
access¶
AccessClient ¶
AccessClient(*, session: SyncSession)
Bases: Resource
Read and change who may edit and who may fill a form.
get ¶
get(survey_id: str) -> ItemList[Permission]
GET /surveys/{id}/access → one permission per action (change, submit).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
Returns:
| Type | Description |
|---|---|
ItemList[Permission]
|
One permission per action. |
Examples:
>>> forms.access.get("686d0a1b2c3d4e5f000000d0").root[0].access
'restricted'
set ¶
set(survey_id: str, body: dict[str, Any]) -> ItemList[Permission]
POST /surveys/{id}/access — set one action's level from a dumped AccessUpdate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
body
|
dict[str, Any]
|
The dumped |
required |
Returns:
| Type | Description |
|---|---|
ItemList[Permission]
|
The permissions after the change. |
Examples:
>>> forms.access.set(
... "686d0a1b2c3d4e5f000000d0", {"action": "submit", "access": "common"}
... ).root[1].access
'common'
grant ¶
grant(survey_id: str, body: dict[str, Any]) -> ItemList[Permission]
POST /surveys/{id}/access/grant — add a user or group (a dumped AccessGrant).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
body
|
dict[str, Any]
|
The dumped |
required |
Returns:
| Type | Description |
|---|---|
ItemList[Permission]
|
The permissions after the change. |
Examples:
>>> forms.access.grant(
... "686d0a1b2c3d4e5f000000d0",
... {"action": "change", "user": {"uid": "7001", "cloud_uid": "cloud-7001"}},
... ).root[0].action
'change'
revoke ¶
revoke(survey_id: str, body: dict[str, Any]) -> ItemList[Permission]
POST /surveys/{id}/access/revoke — remove a user or group (AccessRevoke).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
body
|
dict[str, Any]
|
The dumped |
required |
Returns:
| Type | Description |
|---|---|
ItemList[Permission]
|
The permissions after the change. |
Examples:
>>> forms.access.revoke(
... "686d0a1b2c3d4e5f000000d0",
... {"action": "submit", "group": {"src": "staff", "id": "42"}},
... ).root[1].action
'submit'
history¶
HistoryClient ¶
HistoryClient(*, session: SyncSession)
Bases: Resource
Read the change log of a form.
list ¶
list(survey_id: str, *, ordering: str | None = None, limit: int | None = None) -> ItemList[HistoryEvent]
GET /surveys/{id}/history → the form's changes, page by page, at most limit.
ordering is desc (newest first, the API default) or asc.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
ordering
|
str | None
|
|
None
|
limit
|
int | None
|
The most events to return; |
None
|
Returns:
| Type | Description |
|---|---|
ItemList[HistoryEvent]
|
The form's change events. |
Examples:
>>> events = forms.history.list("686d0a1b2c3d4e5f000000e1", ordering="asc", limit=500)
>>> [event.model for event in events.root]
['servicesurveyhooksubscription', 'surveyhook']
answers¶
AnswersClient ¶
AnswersClient(*, session: SyncSession)
Bases: Resource
Read answers, list them page by page, and export them.
get ¶
get(*, answer_id: int | None = None, answer_key: str | None = None) -> AnswerDetails
GET /answers?answer_id=… (or ?answer_key=…) → one full :class:AnswerDetails.
Exactly one selector: answer_id (the numeric id from a listing; needs form-edit
access) or answer_key (the answer's hash; works without form-edit access).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
answer_id
|
int | None
|
The numeric answer id. |
None
|
answer_key
|
str | None
|
The answer's hash. |
None
|
Returns:
| Type | Description |
|---|---|
AnswerDetails
|
The full answer. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If both or neither of |
Examples:
>>> forms.answers.get(answer_id=2469549806).survey.name
'Feedback'
list ¶
list(survey_id: str, *, questions: str | None = None, use_slugs: bool = False, date_from: str | None = None, date_to: str | None = None, ordering: str | None = None, page_size: int | None = None, answer_format: str | None = None) -> AnswersResponse
GET /surveys/{id}/answers → the first page's {columns, answers, next} envelope.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
questions
|
str | None
|
The comma-separated question ids to return answers for. |
None
|
use_slugs
|
bool
|
Name questions and options by slug instead of id. |
False
|
date_from
|
str | None
|
ISO-8601 start of the period the answers were given in. |
None
|
date_to
|
str | None
|
ISO-8601 end of that period. |
None
|
ordering
|
str | None
|
|
None
|
page_size
|
int | None
|
The most answers a page holds (the API's default is 25). |
None
|
answer_format
|
str | None
|
|
None
|
Returns:
| Type | Description |
|---|---|
AnswersResponse
|
The first page of answers, with its columns. |
Examples:
>>> forms.answers.list("686d0a1b2c3d4e5f00000030").columns[0].slug
'answer_short_text_1'
list_all ¶
list_all(survey_id: str, *, limit: int | None = None, questions: str | None = None, use_slugs: bool = False, date_from: str | None = None, date_to: str | None = None, ordering: str | None = None, page_size: int | None = None, answer_format: str | None = None) -> AnswersResponse
Every answer across pages, at most limit (None = all).
columns come from the first page (identical across pages); the merged next is
None.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
limit
|
int | None
|
The most answers to return; |
None
|
questions
|
str | None
|
The comma-separated question ids to return answers for. |
None
|
use_slugs
|
bool
|
Name questions and options by slug instead of id. |
False
|
date_from
|
str | None
|
ISO-8601 start of the period the answers were given in. |
None
|
date_to
|
str | None
|
ISO-8601 end of that period. |
None
|
ordering
|
str | None
|
|
None
|
page_size
|
int | None
|
The most answers a page holds (the API's default is 25). |
None
|
answer_format
|
str | None
|
|
None
|
Returns:
| Type | Description |
|---|---|
AnswersResponse
|
The answers of every page, with the first page's columns. |
Examples:
>>> len(forms.answers.list_all("686d0a1b2c3d4e5f00000030", limit=500).answers)
1
export ¶
export(survey_id: str, body: dict[str, Any]) -> OperationResult
POST /surveys/{id}/answers/export — start an export → 202 with its operation.
Build body from an AnswerExport; poll :meth:export_results (or
operations.get) on the returned id until ready, then :meth:download_export.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
body
|
dict[str, Any]
|
The dumped |
required |
Returns:
| Type | Description |
|---|---|
OperationResult
|
The export operation, with its |
Examples:
>>> forms.answers.export(
... "686d0a1b2c3d4e5f00000030", {"format": "csv", "upload": "disk"}
... ).id
'op-77'
export_results ¶
export_results(survey_id: str, task_id: str) -> OperationResult
GET /surveys/{id}/answers/export-results?task_id= → the export's status.
While running or failed it answers {id, status, message}; once ready it redirects to
the exported file, reported as a terminal ok.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
task_id
|
str
|
The export operation's |
required |
Returns:
| Type | Description |
|---|---|
OperationResult
|
The export's status. |
Examples:
>>> forms.answers.export_results("686d0a1b2c3d4e5f00000030", "op-77").status
'running'
download_export ¶
download_export(survey_id: str, task_id: str) -> bytes
The exported file's raw bytes, once :meth:export_results reports it ready.
Binary payload — SDK and CLI only, never an MCP result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
task_id
|
str
|
The export operation's |
required |
Returns:
| Type | Description |
|---|---|
bytes
|
The exported file's raw bytes. |
Examples:
>>> forms.answers.export_results("686d0a1b2c3d4e5f00000030", "op-77").status # poll
'running'
>>> # ...until it is no longer running, then:
>>> forms.answers.download_export("686d0a1b2c3d4e5f00000030", "op-77").splitlines()[0]
b'id,name'
integrations_list ¶
integrations_list(*, answer_id: int | None = None, answer_key: str | None = None) -> ItemList[AnswerIntegration]
GET /answers/integrations → the integration runs one answer triggered.
Exactly one selector, as for :meth:get.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
answer_id
|
int | None
|
The numeric answer id. |
None
|
answer_key
|
str | None
|
The answer's hash. |
None
|
Returns:
| Type | Description |
|---|---|
ItemList[AnswerIntegration]
|
The integration runs the answer triggered. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If both or neither of |
Examples:
>>> forms.answers.integrations_list(answer_id=2542485382).root[0].status
'success'
delete ¶
delete(survey_id: str, answer_id: int) -> None
DELETE /surveys/{id}/answers/{answer_id} — delete an answer; see :meth:restore.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
answer_id
|
int
|
The numeric answer id. |
required |
Examples:
>>> forms.answers.delete("686d0a1b2c3d4e5f00000031", 2542485431)
restore ¶
restore(survey_id: str, answer_id: int) -> None
POST /surveys/{id}/answers/{answer_id}/restore — bring a deleted answer back.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
answer_id
|
int
|
The numeric answer id. |
required |
Examples:
>>> forms.answers.restore("686d0a1b2c3d4e5f00000032", 2542485498)
keysets¶
KeysetsClient ¶
KeysetsClient(*, session: SyncSession)
Bases: Resource
List, get, create, modify, delete and download a form's key sets.
list ¶
list(survey_id: str) -> ItemList[Keyset]
GET /surveys/{id}/keysets → every key set (a bare, unpaged array).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
Returns:
| Type | Description |
|---|---|
ItemList[Keyset]
|
Every key set of the form. |
Examples:
>>> forms.keysets.list("686d0a1b2c3d4e5f00000020").root[0].name
'Q1 invites'
get ¶
get(survey_id: str, keyset_id: int) -> Keyset
GET /surveys/{id}/keysets/{keyset_id} → a single :class:Keyset.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
keyset_id
|
int
|
The key set's id. |
required |
Returns:
| Type | Description |
|---|---|
Keyset
|
The key set. |
Examples:
>>> forms.keysets.get("686d0a1b2c3d4e5f00000020", 3).id
3
create ¶
create(survey_id: str, body: dict[str, Any]) -> Keyset
POST /surveys/{id}/keysets — create a key set from a dumped KeysetCreate.
The API requires is_enabled on create, alongside name and total.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
body
|
dict[str, Any]
|
The dumped |
required |
Returns:
| Type | Description |
|---|---|
Keyset
|
The created key set, with its |
Examples:
>>> forms.keysets.create(
... "686d0a1b2c3d4e5f00000020",
... {"name": "Q1 invites", "total": 100, "is_enabled": True},
... ).id
3
modify ¶
modify(survey_id: str, keyset_id: int, body: dict[str, Any]) -> Keyset
PATCH /surveys/{id}/keysets/{keyset_id} — replace a key set → the :class:Keyset.
Despite the method, the API validates a full record: name, total and
is_enabled are all required (a KeysetUpdate with every field set).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
keyset_id
|
int
|
The key set's id. |
required |
body
|
dict[str, Any]
|
The dumped |
required |
Returns:
| Type | Description |
|---|---|
Keyset
|
The replaced key set. |
Examples:
>>> forms.keysets.modify(
... "686d0a1b2c3d4e5f00000020",
... 4,
... {"name": "Q1 invites", "total": 100, "is_enabled": True},
... ).name
'Q1 invites'
delete ¶
delete(survey_id: str, keyset_id: int) -> None
DELETE /surveys/{id}/keysets/{keyset_id} — delete a key set (no body comes back).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
keyset_id
|
int
|
The key set's id. |
required |
Examples:
>>> forms.keysets.delete("686d0a1b2c3d4e5f00000020", 5)
download ¶
download(survey_id: str, keyset_id: int) -> bytes
GET /surveys/{id}/keysets/{keyset_id}/download → the key set's raw bytes.
Binary payload — SDK and CLI only, never an MCP result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
keyset_id
|
int
|
The key set's id. |
required |
Returns:
| Type | Description |
|---|---|
bytes
|
The key set's raw bytes. |
Examples:
>>> forms.keysets.download("686d0a1b2c3d4e5f00000020", 6)[:5]
b'key-1'
operations¶
OperationsClient ¶
OperationsClient(*, session: SyncSession)
Bases: Resource
Read the status of an asynchronous Forms operation.
get ¶
get(operation_id: str) -> OperationResult
GET /operations/{operation_id} → the operation's current :class:OperationResult.
Poll it on the id an async trigger returned (answers export --no-wait) until
:attr:OperationResult.is_terminal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
operation_id
|
str
|
The operation's |
required |
Returns:
| Type | Description |
|---|---|
OperationResult
|
The operation's current state. |
Examples:
>>> forms.operations.get("op-4a1b").is_terminal
True
notifications¶
NotificationsClient ¶
NotificationsClient(*, session: SyncSession)
Bases: Resource
List, inspect, restart and cancel the runs of a form's integrations.
list ¶
list(*, survey_id: str | None = None, hook_id: int | None = None, subscription_id: int | None = None, answer_id: int | None = None, status: Sequence[str] | None = None, created_since: str | None = None, created_until: str | None = None, finished_since: str | None = None, finished_until: str | None = None, visible: bool | None = None, integration_type: str | None = None, ordering: str | None = None, limit: int | None = None) -> ItemList[Notification]
GET /notifications → runs matching every filter given, at most limit.
status holds any of pending, success, error, canceled; the *_since / *_until
bounds are ISO-8601 times (both ends inclusive); ordering is asc (the API
default) or desc.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str | None
|
Only runs of this form. |
None
|
hook_id
|
int | None
|
Only runs of this integration group. |
None
|
subscription_id
|
int | None
|
Only runs of this integration. |
None
|
answer_id
|
int | None
|
Only runs triggered by this answer. |
None
|
status
|
Sequence[str] | None
|
Only runs in any of these states. |
None
|
created_since
|
str | None
|
Only runs created at or after this time. |
None
|
created_until
|
str | None
|
Only runs created at or before this time. |
None
|
finished_since
|
str | None
|
Only runs finished at or after this time. |
None
|
finished_until
|
str | None
|
Only runs finished at or before this time. |
None
|
visible
|
bool | None
|
Only visible ( |
None
|
integration_type
|
str | None
|
Only runs of this integration type. |
None
|
ordering
|
str | None
|
|
None
|
limit
|
int | None
|
The most runs to return; |
None
|
Returns:
| Type | Description |
|---|---|
ItemList[Notification]
|
The matching runs. |
Examples:
>>> runs = forms.notifications.list(
... survey_id="686d0a1b2c3d4e5f000000f0", status=["error", "pending"], limit=500
... )
>>> [run.id for run in runs.root]
[9001, 9002, 9003]
get ¶
get(notification_id: int) -> NotificationDetails
GET /notifications/{id} → the run with its context, response and error.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
notification_id
|
int
|
The run's id. |
required |
Returns:
| Type | Description |
|---|---|
NotificationDetails
|
The run, with what the integration was given, answered and failed with. |
Examples:
>>> forms.notifications.get(9100).error[0].name
'detail'
status_get ¶
status_get(notification_id: int) -> NotificationStatus
GET /notifications/{id}/status → just the run's state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
notification_id
|
int
|
The run's id. |
required |
Returns:
| Type | Description |
|---|---|
NotificationStatus
|
The run's state. |
Examples:
>>> forms.notifications.status_get(9101).status
'success'
restart ¶
restart(notification_id: int) -> NotificationAction
POST /notifications/{id}/restart — run the integration again for that answer.
result.status is ok, skip (a run that is still pending is left alone),
fail (see detail) or operation: the run was queued again. A canceled run
answered operation with the operation_id not-supported on the test
organization, so there is nothing to poll: read the run's state with :meth:status_get.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
notification_id
|
int
|
The run's id. |
required |
Returns:
| Type | Description |
|---|---|
NotificationAction
|
How the restart went. |
Examples:
>>> forms.notifications.restart(9102).result.status
'operation'
cancel ¶
cancel(notification_id: int) -> NotificationAction
POST /notifications/{id}/cancel — stop a run that has not finished.
A run that is already canceled or finished answers result.status skip.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
notification_id
|
int
|
The run's id. |
required |
Returns:
| Type | Description |
|---|---|
NotificationAction
|
How the cancel went. |
Examples:
>>> forms.notifications.cancel(9103).result.status
'fail'
errors_list ¶
errors_list(survey_id: str) -> ItemList[int]
GET /surveys/{id}/show-errors → ids of the form's failed runs still shown.
Read each with :meth:get.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
Returns:
| Type | Description |
|---|---|
ItemList[int]
|
The ids of the form's failed runs. |
Examples:
>>> forms.notifications.errors_list("686d0a1b2c3d4e5f000000f2").root
[9001, 9003]
files¶
FilesClient ¶
FilesClient(*, session: SyncSession)
Bases: Resource
The files attached while filling a form.
upload ¶
upload(survey_id: str, *, filename: str, data: bytes) -> FileOut
Upload a file for form filling (multipart field file) → :class:FileOut.
Needs external file storage connected in the form's settings; the returned path /
url then reference the file in a File-type answer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
filename
|
str
|
The file's name. |
required |
data
|
bytes
|
The file's raw bytes. |
required |
Returns:
| Type | Description |
|---|---|
FileOut
|
The stored file, with its |
Examples:
>>> forms.files.upload(
... "686d0a1b2c3d4e5f00000040", filename="cv.txt", data=b"resume bytes"
... ).path
'a/b/cv.txt'
verify ¶
verify(survey_id: str, files: list[FileIn]) -> ItemList[FileOut]
POST …/files/verify (a read) → the upload status and access of each file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
files
|
list[FileIn]
|
The files to check, each by |
required |
Returns:
| Type | Description |
|---|---|
ItemList[FileOut]
|
The upload status and access of each file. |
Examples:
>>> forms.files.verify(
... "686d0a1b2c3d4e5f00000040",
... [
... FileIn(path="a/b/cv.txt", url="https://forms.test/a/b/cv.txt"),
... FileIn(path="c/d.pdf"),
... ],
... ).root[0].check_status
'ready'
download ¶
download(path: str, *, download: bool = False, file_hash: str | None = None) -> bytes
GET /files?path=… → a stored file's raw bytes.
download=True asks for a Content-Disposition filename header; file_hash (the
hash from an upload) lets an anonymous caller download a file whose access cannot
otherwise be verified.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
The stored file's path. |
required |
download
|
bool
|
Whether to ask for a |
False
|
file_hash
|
str | None
|
The |
None
|
Returns:
| Type | Description |
|---|---|
bytes
|
The file's raw bytes. |
Examples:
>>> forms.files.download("a/b/cv.txt", download=True, file_hash="h4sh")
b'resume bytes'
delete ¶
delete(*, path: str | None = None, url: str | None = None) -> Ack
DELETE /files (body {path, url}) → an :class:Ack naming what was given.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | None
|
The stored file's path. |
None
|
url
|
str | None
|
The stored file's url. |
None
|
Returns:
| Type | Description |
|---|---|
Ack
|
An acknowledgement naming the deleted file. |
Examples:
>>> forms.files.delete(path="a/b/cv.txt", url="https://forms.test/a/b/cv.txt").ok
True
images¶
ImagesClient ¶
ImagesClient(*, session: SyncSession)
Bases: Resource
Images to reference from a form's questions, options or style.
upload ¶
upload(survey_id: str, *, filename: str, data: bytes) -> Image
Upload an image (multipart field image) → :class:Image.
Reference the returned id from a question's, option's or form style's image.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
filename
|
str
|
The image's file name. |
required |
data
|
bytes
|
The image's raw bytes. |
required |
Returns:
| Type | Description |
|---|---|
Image
|
The uploaded image, with its |
Examples:
>>> forms.images.upload(
... "686d0a1b2c3d4e5f00000050", filename="logo.png", data=b"PNGDATA"
... ).id
7
clone ¶
clone(survey_id: str, body: dict[str, Any]) -> Image
POST /surveys/{id}/images/clone — copy an existing image into the form.
Build body from an ImageClone: the source image's id (or its links) and
an optional new name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
body
|
dict[str, Any]
|
The dumped |
required |
Returns:
| Type | Description |
|---|---|
Image
|
The copied image, with its new |
Examples:
>>> forms.images.clone("686d0a1b2c3d4e5f00000051", {"id": 7, "name": "copy.png"}).id
8
filling¶
FillingClient ¶
FillingClient(*, session: SyncSession)
Bases: Resource
Fill a form the way a respondent does.
get ¶
get(survey: str, key: str | None = None) -> FillableForm
GET /surveys/{survey}/form → the :class:FillableForm settings for filling.
survey is the form id, its slug, or an id+verification-key combination; key is
the personal-link fill key. The call also checks that the form is published and fillable.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey
|
str
|
The form's id, slug, or id+verification-key combination. |
required |
key
|
str | None
|
The personal-link fill key. |
None
|
Returns:
| Type | Description |
|---|---|
FillableForm
|
The form's settings for filling. |
Examples:
>>> forms.filling.get("686d0a1b2c3d4e5f00000060", key="k-1").name
'Feedback'
submit ¶
submit(survey: str, body: SubmitBody, *, dry_run: bool = False, key: str | None = None) -> SubmitResult
POST /surveys/{survey}/form — submit a response → :class:SubmitResult.
body maps each question slug to its answer. dry_run=True validates
everything but saves nothing and fires no integrations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey
|
str
|
The form's id, slug, or id+verification-key combination. |
required |
body
|
SubmitBody
|
The answers, keyed by question |
required |
dry_run
|
bool
|
Whether to validate only, saving nothing. |
False
|
key
|
str | None
|
The personal-link fill key. |
None
|
Returns:
| Type | Description |
|---|---|
SubmitResult
|
The submission result, with the new answer's id. |
Examples:
>>> from ycli.yandex.forms.filling.models import SubmitBody
>>> body = SubmitBody.model_validate({"name": "Ann", "rating": 5})
>>> forms.filling.submit("686d0a1b2c3d4e5f00000060", body, key="k-2").answer_id
99
suggest ¶
suggest(survey: str, *, question: str | None = None, text: str | None = None, suggest_id: str | None = None, parent_id: str | None = None) -> ItemList[Suggestion]
GET /surveys/{survey}/suggest → prompts for a fill field (read-only).
question is the question slug, text the search text, suggest_id (the API's
id) a comma-separated list of suggestion ids to resolve, and parent_id scopes a
Master/Detail lookup.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey
|
str
|
The form's id, slug, or id+verification-key combination. |
required |
question
|
str | None
|
The question's slug. |
None
|
text
|
str | None
|
The search text. |
None
|
suggest_id
|
str | None
|
A comma-separated list of suggestion ids to resolve. |
None
|
parent_id
|
str | None
|
The parent id scoping a Master/Detail lookup. |
None
|
Returns:
| Type | Description |
|---|---|
ItemList[Suggestion]
|
The suggestions for the field. |
Examples:
>>> forms.filling.suggest("686d0a1b2c3d4e5f00000060", question="city", text="Ber").root[
... 0
... ].text
'Berlin'
hooks¶
HooksClient ¶
HooksClient(*, session: SyncSession)
Bases: Resource
List, get, create, modify and delete a form's integration groups.
list ¶
list(survey_id: str) -> ItemList[Hook]
GET /surveys/{id}/hooks → every integration group with its integrations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
Returns:
| Type | Description |
|---|---|
ItemList[Hook]
|
Every integration group, with its integrations. |
Examples:
>>> forms.hooks.list("686d0a1b2c3d4e5f000000a0").root[0].name
'CRM'
get ¶
get(survey_id: str, hook_id: int) -> Hook
GET /surveys/{id}/hooks/{hook_id} → one :class:Hook.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
hook_id
|
int
|
The integration group's (hook's) id. |
required |
Returns:
| Type | Description |
|---|---|
Hook
|
The integration group. |
Examples:
>>> forms.hooks.get("686d0a1b2c3d4e5f000000a0", 12).active
False
create ¶
create(survey_id: str, body: dict[str, Any]) -> Hook
POST /surveys/{id}/hooks — create a group from a dumped HookCreate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
body
|
dict[str, Any]
|
The dumped |
required |
Returns:
| Type | Description |
|---|---|
Hook
|
The created integration group, with its |
Examples:
>>> forms.hooks.create("686d0a1b2c3d4e5f000000a0", {"name": "CRM", "active": False}).id
13
modify ¶
modify(survey_id: str, hook_id: int, body: dict[str, Any]) -> Hook
PATCH /surveys/{id}/hooks/{hook_id} — only the keys in body change.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
hook_id
|
int
|
The integration group's (hook's) id. |
required |
body
|
dict[str, Any]
|
The keys to change. |
required |
Returns:
| Type | Description |
|---|---|
Hook
|
The updated integration group. |
Examples:
>>> forms.hooks.modify("686d0a1b2c3d4e5f000000a0", 15, {"name": "CRM"}).name
'CRM'
delete ¶
delete(survey_id: str, hook_id: int) -> None
DELETE /surveys/{id}/hooks/{hook_id} — the group and its integrations (200).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
hook_id
|
int
|
The integration group's (hook's) id. |
required |
Examples:
>>> forms.hooks.delete("686d0a1b2c3d4e5f000000a0", 16)
subscriptions¶
SubscriptionsClient ¶
SubscriptionsClient(*, session: SyncSession)
Bases: Resource
List, get, create, modify and delete the integrations of a hook; upload attachments.
list ¶
list(survey_id: str, hook_id: int) -> ItemList[Subscription]
GET /surveys/{id}/hooks/{hook_id}/subscriptions → every integration of the hook.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
hook_id
|
int
|
The integration group's (hook's) id. |
required |
Returns:
| Type | Description |
|---|---|
ItemList[Subscription]
|
Every integration of the hook. |
Examples:
>>> forms.subscriptions.list("686d0a1b2c3d4e5f000000b0", 21).root[0].type
'http'
get ¶
get(survey_id: str, hook_id: int, subscription_id: int) -> Subscription
GET …/subscriptions/{subscription_id} → one integration, typed by type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
hook_id
|
int
|
The integration group's (hook's) id. |
required |
subscription_id
|
int
|
The integration's id. |
required |
Returns:
| Type | Description |
|---|---|
Subscription
|
The integration. |
Examples:
>>> forms.subscriptions.get("686d0a1b2c3d4e5f000000b0", 21, 4).type
'tracker'
create ¶
create(survey_id: str, hook_id: int, body: Subscription) -> Subscription
POST …/subscriptions — add an integration to the hook → it, with its id.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
hook_id
|
int
|
The integration group's (hook's) id. |
required |
body
|
Subscription
|
The new integration. |
required |
Returns:
| Type | Description |
|---|---|
Subscription
|
The created integration, with its |
Examples:
>>> from ycli.yandex.forms.subscriptions.models import HttpSubscription
>>> forms.subscriptions.create(
... "686d0a1b2c3d4e5f000000b0",
... 21,
... HttpSubscription(url="https://example.com/hook", active=False),
... ).id
5
modify ¶
modify(survey_id: str, hook_id: int, subscription_id: int, body: Subscription) -> Subscription
PATCH …/subscriptions/{subscription_id} — change the fields set in body.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
hook_id
|
int
|
The integration group's (hook's) id. |
required |
subscription_id
|
int
|
The integration's id. |
required |
body
|
Subscription
|
The fields to change. |
required |
Returns:
| Type | Description |
|---|---|
Subscription
|
The updated integration. |
Examples:
>>> from ycli.yandex.forms.subscriptions.models import HttpSubscription
>>> forms.subscriptions.modify(
... "686d0a1b2c3d4e5f000000b0", 21, 6, HttpSubscription(active=False)
... ).active
False
delete ¶
delete(survey_id: str, hook_id: int, subscription_id: int) -> None
DELETE …/subscriptions/{subscription_id} (200, no body).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
hook_id
|
int
|
The integration group's (hook's) id. |
required |
subscription_id
|
int
|
The integration's id. |
required |
Examples:
>>> forms.subscriptions.delete("686d0a1b2c3d4e5f000000b0", 21, 8)
attach ¶
attach(survey_id: str, hook_id: int, subscription_id: int, *, filename: str, data: bytes) -> FileOut
Upload a fixed attachment (multipart field file) → its path.
Reference the returned path from attachments.static in a subscription body.
Binary payload — SDK and CLI only.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
hook_id
|
int
|
The integration group's (hook's) id. |
required |
subscription_id
|
int
|
The integration's id. |
required |
filename
|
str
|
The attachment's file name. |
required |
data
|
bytes
|
The attachment's raw bytes. |
required |
Returns:
| Type | Description |
|---|---|
FileOut
|
The stored attachment, with its |
Examples:
>>> forms.subscriptions.attach(
... "686d0a1b2c3d4e5f000000b0", 21, 9, filename="terms.pdf", data=b"%PDF"
... ).path
'/forms/terms.pdf'
variables¶
VariablesClient ¶
VariablesClient(*, session: SyncSession)
Bases: Resource
The variable types a form's integrations can reference.
list ¶
list(survey_id: str) -> ItemList[VariableInfo]
GET /surveys/{id}/variables → every variable type available to the form.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
survey_id
|
str
|
The form's id. |
required |
Returns:
| Type | Description |
|---|---|
ItemList[VariableInfo]
|
Every variable type available to the form. |
Examples:
>>> forms.variables.list("686d0a1b2c3d4e5f000000c0").root[0].type
'form.answer_url'