Skip to main content

formable-sdk

Official Python SDK for the Formable API (v1). Covers templates, signature requests, redlining, and billing.

  • Sync (Formable) and async (AsyncFormable) clients
  • Fully typed requests and responses (py.typed)
  • Python 3.9+

Installation

pip install formable-sdk

Usage

import os
from formable import Formable

formable = Formable(api_key=os.environ["FORMABLE_API_KEY"])

Templates

with open("nda.docx", "rb") as f:
    result = formable.templates.create(
        file=f.read(),
        filename="nda.docx",
        signer_roles=[
            {"name": "Client", "order": 0},
            {"name": "Witness", "order": 1},
        ],
    )

template_id = result["templateId"]

# Mint a fresh edit URL later (expires after 1 day)
edit = formable.templates.create_edit_url(template_id)
print(edit["editUrl"], edit["expiresAt"])

Signature requests

# Formable emails each signer a signing link
request = formable.signature_requests.create(
    template_id=template_id,
    signers=[
        {"email": "jane@example.com", "name": "Jane Doe", "role": "Client"},
        {"email": "bob@example.com", "name": "Bob Smith", "role": "Witness"},
    ],
)

# Embedded flow: mint signing URLs to embed in an iframe yourself
embedded = formable.signature_requests.create_embedded(
    template_id=template_id,
    signers=[{"email": "jane@example.com", "name": "Jane Doe", "role": "Client"}],
    test_mode=True,
)

signer = embedded["signers"][0]
signing = formable.signature_requests.create_signing_url(
    signer["recipientSignatureId"]
)

# Track progress
from datetime import datetime, timezone

current = formable.signature_requests.get(embedded["signatureRequestId"])
all_requests = formable.signature_requests.list(
    updated_since=datetime(2026, 1, 1, tzinfo=timezone.utc)
)
events = formable.signature_requests.get_events(embedded["signatureRequestId"])

# Download the signed document once completed
envelope = formable.signature_requests.get_signed_envelope(
    embedded["signatureRequestId"]
)
print(envelope["signedEnvelopePresignedUrl"])

Redline requests

created = formable.redline_requests.create(
    template_id=template_id,
    members=[
        {"email": "us@example.com", "display_name": "John Doe", "role": "DisclosingParty"},
        {"email": "them@example.com", "display_name": "Jane Smith", "role": "ReceivingParty"},
    ],
    metadata={"subject": "Mutual NDA"},
)

redline_request_id = created["redlineRequestId"]

# Mint a redline URL for a member (embed in an iframe)
url = formable.redline_requests.create_url(redline_request_id, "them@example.com")

# Manage members and track progress
formable.redline_requests.update_members(
    redline_request_id,
    [{"email": "counsel@example.com", "display_name": "Counsel", "role": "ReceivingCounsel"}],
)
redline = formable.redline_requests.get(redline_request_id)
events = formable.redline_requests.get_events(redline_request_id)

Billing and health

billing = formable.billing()
print(billing["numberOfRedliningSessions"])

health = formable.health()

Async client

Every method is also available on AsyncFormable with the same signatures.

import asyncio
from formable import AsyncFormable

async def main():
    async with AsyncFormable(api_key=os.environ["FORMABLE_API_KEY"]) as formable:
        health = await formable.health()

asyncio.run(main())

Error handling

All non-2xx responses raise a FormableError with the server's error message, HTTP status, and parsed response body.

from formable import FormableError

try:
    formable.signature_requests.get("missing-id")
except FormableError as error:
    print(error.status, error)

Configuration

Option Description Default
api_key Your Formable API key (sent as a bearer token). Required. -
base_url Override the API base URL. https://api.formabledocs.com/v1
client Custom httpx.Client (or httpx.AsyncClient for async). Built-in client with 60s timeout

Development

python3 -m venv .venv
.venv/bin/pip install -e . pytest mypy build
.venv/bin/python -m pytest tests
.venv/bin/python -m mypy src/formable

Publishing

.venv/bin/python -m build
.venv/bin/python -m pip install twine
.venv/bin/python -m twine upload dist/*

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

formable_sdk-0.1.0.tar.gz (8.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

formable_sdk-0.1.0-py3-none-any.whl (11.3 kB view details)

Uploaded Python 3

File details

Details for the file formable_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: formable_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 8.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.5

File hashes

Hashes for formable_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 32c20e12c98ebb7bcf424ae2333fdb402dfaba9f08c92881ae5b88b7b59c0bc9
MD5 58b19e040f79a06d36b1edf49284b183
BLAKE2b-256 fce9c12795cdac737bcc010540d016a5925dfae41f5a022b056c6e2af33cf1ec

See more details on using hashes here.

File details

Details for the file formable_sdk-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: formable_sdk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 11.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.5

File hashes

Hashes for formable_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cf6fb0a1078a0258bb51165cd6effa9cbf7098beacd106a258509dedc4af89a7
MD5 7f4ef15d41d49e50e56318cf9c32ceeb
BLAKE2b-256 0e15c07e3a62f00e6cc39459c8dc2a1df39cffeb2e549812f476e6190136e7b2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page