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/*

Metadata

Release files for formable-sdk 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for formable-sdk 0.1.1
File Size Uploaded
formable_sdk-0.1.1.tar.gz 9.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for formable-sdk 0.1.1
File Interpreter ABI Platform
formable_sdk-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 20.6 kB

Release files / formable_sdk-0.1.1.tar.gz

Download URL formable_sdk-0.1.1.tar.gz
Size 9.1 kB
Tags Source
SHA-256 checksum
How to use checksums
05be6e94714a2fc7f8a85870d1a6151d905258b78115d56eb434acfb161b5d92
BLAKE2b-256 checksum
How to use checksums
0f800cdcef22103a90ea52eecdc52c8db0dd880207784b82aaebe7835522dbee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.5

Release files / formable_sdk-0.1.1-py3-none-any.whl

Download URL formable_sdk-0.1.1-py3-none-any.whl
Size 11.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5a7f6790771129ab67f44cd7ec7ebd6ae683d3fac3620a513fbc8cf8a78d3b68
BLAKE2b-256 checksum
How to use checksums
1b4021f4dc77f8b34243332f012600ab4f0397bc26f6e57b3abe6a34c502f5de
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.5

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page