Python SDK
Install and use the official Formalingo Python SDK.
Python SDK
The formalingo-sdk package provides a type-safe client for the Formalingo API, generated with Microsoft Kiota.
Installation
pip install git+https://github.com/Formalingo/sdk-python.gitOr with uv:
uv pip install git+https://github.com/Formalingo/sdk-python.gitSetup
from formalingo import create_client
client = create_client("af_live_YOUR_KEY")The create_client helper wires up authentication and the HTTP adapter automatically. You can optionally pass a custom base URL:
client = create_client("af_live_YOUR_KEY", base_url="https://staging.formalingo.com")Note: The Kiota-generated client includes the full API path:
client.api.v1.forms,client.api.v1.documents, etc.
Forms
List forms
forms = await client.api.v1.forms.get()Create a form
from formalingo.models.create_form_body import CreateFormBody
body = CreateFormBody()
body.title = "Customer Satisfaction Survey"
body.description = "Help us improve our service."
form = await client.api.v1.forms.post(body)Get a form
form = await client.api.v1.forms.by_form_id("FORM_ID").get()Update a form
from formalingo.models.update_form_body import UpdateFormBody
body = UpdateFormBody()
body.status = "published"
form = await client.api.v1.forms.by_form_id("FORM_ID").put(body)Delete a form
await client.api.v1.forms.by_form_id("FORM_ID").delete()Sections
# List sections
sections = await client.api.v1.forms.by_form_id("FORM_ID").sections.get()
# Create a section
from formalingo.models.create_section_body import CreateSectionBody
body = CreateSectionBody()
body.title = "Personal Information"
section = await client.api.v1.forms.by_form_id("FORM_ID").sections.post(body)Questions
from formalingo.models.create_question_body import CreateQuestionBody
# Create a text question
body = CreateQuestionBody()
body.question_text = "What is your full name?"
body.type = "short_text"
body.is_required = True
question = await client.api.v1.forms.by_form_id("FORM_ID").questions.post(body)Recipients
from formalingo.models.create_recipient_body import CreateRecipientBody
body = CreateRecipientBody()
body.label = "John Doe"
body.email = "john@acme.com"
body.prefill = {
"question-uuid-1": "John Doe",
"question-uuid-2": "Acme Corp",
}
recipient = await client.api.v1.forms.by_form_id("FORM_ID").recipients.post(body)
print(recipient.link)
# → https://www.formalingo.com/f/TOKEN
# Bulk create with one caller-owned retry key for the exact request
from uuid import UUID
from formalingo import create_bulk_recipients
from formalingo.api.v1.forms.item.recipients.bulk.bulk_post_request_body import BulkPostRequestBody
from formalingo.api.v1.forms.item.recipients.bulk.bulk_post_request_body_recipients import BulkPostRequestBody_recipients
bulk_body = BulkPostRequestBody(
confirm_bulk=True,
recipients=[
BulkPostRequestBody_recipients(
label="Alice",
email="alice@example.com",
),
],
)
recipients = await create_bulk_recipients(
client,
UUID("00000000-0000-0000-0000-000000000001"),
bulk_body,
"recipient-bulk-create-7f3f",
)The idempotency key is required. Reuse it only when retrying the exact same serialized request body.
On idempotency_request_in_progress, retry the exact body with the same key. A different body returns idempotency_key_conflict; recipient erasure returns idempotency_replay_unavailable.
Branding
from formalingo.models.branding_update_request import BrandingUpdateRequest
body = BrandingUpdateRequest()
body.primary_color = "#6366F1"
body.welcome_heading = "Welcome!"
body.thank_you_heading = "Thank you!"
await client.api.v1.forms.by_form_id("FORM_ID").branding.put(body)Documents
# List documents
docs = await client.api.v1.documents.get()
# Create a submission
from uuid import UUID
from formalingo import create_document_submission
from formalingo.models.create_submission_body import CreateSubmissionBody
from formalingo.models.signer_input import SignerInput
from formalingo.models.signer_input_prefill import SignerInput_prefill
prefill = SignerInput_prefill(
additional_data={"field-uuid-1": "John Doe"},
)
signer = SignerInput(
role="signer_1",
name="John Doe",
email="john@acme.com",
prefill=prefill,
prefill_readonly=True,
)
body = CreateSubmissionBody(signers=[signer])
submission = await create_document_submission(
client,
UUID("00000000-0000-0000-0000-000000000001"),
body,
"document-create-7f3f",
)
print(submission.signers[0].link)
# → https://www.formalingo.com/d/TOKENThe required idempotency key makes retries safe. The helper unwraps the API envelope so submission.signers comes from response.data.signers.
Error Handling
try:
form = await client.api.v1.forms.by_form_id("non-existent").get()
except Exception as error:
print(f"API error: {error}")