Skip to content
Official libraries · Available · v1.0.0

Five official libraries with the same resource interface.

Server libraries (PHP · Node.js · Python) that create and track signature requests and verify event notifications, and two in-app signing libraries (iOS · Android) that show the signing page inside your app with no secret key in it. What you learn in one library applies to the rest.

All the libraries are available now on GitHub and the standard package registries at version v1.0.0.

Available · v1.0.0 MIT licence SemVer versioning
Official libraries

Each library in its own box: installation, requirements and source.

Each box carries the install command, the runtime requirements and the package source, and the GitHub and Package buttons open the repository and the package source.

PHP

API library
Available · v1.0.0

The official server library for PHP: create signature requests, track them and verify event notifications.

Terminal
composer require wthaiq/wthaiq-php
  • PHP 8.1 or later · curl / json extensions
  • Packagist · wthaiq/wthaiq-php

Node.js

API library
Available · v1.0.0

The official server library for Node.js, with complete TypeScript definitions and no runtime dependencies.

Terminal
npm install wthaiq
  • Node.js 18 or later · TypeScript definitions included · ESM / CommonJS
  • npm · wthaiq

Python

API library
Available · v1.0.0

The official server library for Python, with synchronous and asynchronous clients and no required dependencies.

Terminal
pip install wthaiq
  • Python 3.10 or later · no required dependencies
  • PyPI · wthaiq

iOS

In-app signing library
Available · v1.0.0

SwiftUI and UIKit APIs that show the signing page inside your app and report the session result, with no secret key in the app.

Package.swift
.package(url: "https://github.com/wthaiq/wthaiq-ios", from: "1.0.0")
  • iOS 15 or later · Swift 5.9 or later
  • Swift Package · WthaiqSigning

Android

In-app signing library
Available · v1.0.0

Jetpack Compose, Fragment and Activity Result APIs that show the signing page inside your app, with no secret key in the app.

build.gradle.kts
implementation("com.wthaiq:signing:1.0.0")
  • Android 7.0 (minSdk 24) or later · Kotlin / Java
  • Maven Central · com.wthaiq:signing
Detailed guide

Library by library: installation and quick start.

Each library has its install command, a quick start example taken from its guide, what it covers and its runtime requirements.

PHP

API library
Available · v1.0.0

The official server library for PHP: create signature requests, track them and verify event notifications.

Installation

Terminal
composer require wthaiq/wthaiq-php

Quick start

quickstart.php
require 'vendor/autoload.php';

$wthaiq = new \Wthaiq\Client(getenv('WTHAIQ_API_KEY'));
$request = $wthaiq->signatureRequests->create([
    'source'  => ['type' => 'template', 'template_id' => 'tpl_123'],
    'signers' => [['name' => 'Noha Hassan', 'email' => 'noha@example.com']],
]);

echo $request->id . ' ' . $request->status; // sr_3n8Kd2Qa1V... sent
The example reads the key from the environment variable shown in the code. Use an sk_test_ key while you build, so no balance is deducted and no message reaches anyone.

What the library covers

  • Create, send and track signature requests
  • Templates and workflows
  • Embedded signing sessions in your site or app
  • Download the final document and the sealed evidence record
  • Verify event notification (webhook) signatures
  • Free test mode with an sk_test_ key, then live mode by changing the key alone

What sets it apart: Uses cURL by default and accepts any PSR-18 client (Guzzle · Symfony HttpClient), with immutable typed response objects and support for PHP 8.1 to 8.4.

Node.js

API library
Available · v1.0.0

The official server library for Node.js, with complete TypeScript definitions and no runtime dependencies.

Installation

Terminal
npm install wthaiq

Quick start

quickstart.js
import Wthaiq from 'wthaiq';

const wt = new Wthaiq(process.env.WTHAIQ_API_KEY);

const sr = await wt.signatureRequests.create({
  title: 'Employment contract',
  source: { type: 'template', template_id: 'tpl_123' },
  legal_level: 'aes',
  signers: [{ name: 'Ahmed Ali', email: 'ahmed@example.com', method: 'draw', require_identity: true }],
});

console.log(sr.id, sr.status); // sr_3f1c… sent
The example reads the key from the environment variable shown in the code. Use an sk_test_ key while you build, so no balance is deducted and no message reaches anyone.

What the library covers

  • Create, send and track signature requests
  • Templates and workflows
  • Embedded signing sessions in your site or app
  • Download the final document and the sealed evidence record
  • Verify event notification (webhook) signatures
  • Free test mode with an sk_test_ key, then live mode by changing the key alone

What sets it apart: Written in TypeScript with complete definitions, ships ESM and CommonJS, accepts an AbortSignal to cancel a call, and verifies notifications synchronously, including on edge runtimes.

Python

API library
Available · v1.0.0

The official server library for Python, with synchronous and asynchronous clients and no required dependencies.

Installation

Terminal
pip install wthaiq

Quick start

quickstart.py
import os
import wthaiq

wt = wthaiq.Client(os.environ["WTHAIQ_API_KEY"])  # sk_test_... while you build

sr = wt.signature_requests.create(
    title="عقد عمل — أحمد سامي",
    source={"type": "template", "template_id": "tpl_123"},
    legal_level="aes",
    signers=[{"name": "أحمد سامي", "email": "ahmed@example.com", "method": "draw"}],
)

print(sr.id, sr.status)  # sr_3n8Kd2Qa1V... sent
The example reads the key from the environment variable shown in the code. Use an sk_test_ key while you build, so no balance is deducted and no message reaches anyone.

What the library covers

  • Create, send and track signature requests
  • Templates and workflows
  • Embedded signing sessions in your site or app
  • Download the final document and the sealed evidence record
  • Verify event notification (webhook) signatures
  • Free test mode with an sk_test_ key, then live mode by changing the key alone

What sets it apart: A synchronous Client and an asynchronous AsyncClient with the same methods, full typing (py.typed), and optional httpx for true asynchronous I/O.

iOS

In-app signing library
Available · v1.0.0

SwiftUI and UIKit APIs that show the signing page inside your app and report the session result, with no secret key in the app.

Installation

Package.swift
.package(url: "https://github.com/wthaiq/wthaiq-ios", from: "1.0.0")

Quick start

OrderView.swift
import SwiftUI
import WthaiqSigning

struct OrderView: View {
    @State private var signingURL: URL?
    @State private var isSigning = false

    var body: some View {
        Button("Sign the contract") {
            Task {
                signingURL = try? await MyBackend.signingURL(forOrder: 42) // your API call
                isSigning = signingURL != nil
            }
        }
        .wthaiqSigning(isPresented: $isSigning, url: signingURL) { result in
            if case .signed = result { /* confirm on your backend via webhooks */ }
        }
    }
}
The signing link comes from your server (through one of the server libraries or directly through the API), and no key goes into the app. The result the library reports drives your interface; the event notification on your server is the proof.

What the library covers

  • Show the signing page full screen inside the app, not in an external browser
  • Report the result to the app once: signed · declined · canceled · expired · failed
  • In-session events to update your interface
  • Loading, error and retry screens, dark mode, Arabic right-to-left and English
  • ID attachments, camera and identity verification inside the page
  • No key in the app: your server creates the signing link, and the event notification it receives is the proof

What sets it apart: The SwiftUI modifier .wthaiqSigning(isPresented:url:) or WthaiqSigningSheet; in UIKit, presentWthaiqSigning(url:) or WthaiqSigningViewController with a delegate; distributed through Swift Package Manager only.

Android

In-app signing library
Available · v1.0.0

Jetpack Compose, Fragment and Activity Result APIs that show the signing page inside your app, with no secret key in the app.

Installation

build.gradle.kts
implementation("com.wthaiq:signing:1.0.0")

Quick start

OrderActivity.kt
class OrderActivity : ComponentActivity() {

    private val signing = registerForActivityResult(WthaiqSigning.Contract()) { result ->
        when (result) {
            is SigningResult.Signed -> showConfirming(result.outcome.reference.signatureRequestId)
            is SigningResult.Declined -> showDeclined(result.outcome.reason)
            SigningResult.Canceled -> Unit
            SigningResult.Expired -> requestNewLink()
            is SigningResult.Failed -> showError(result.error)
        }
    }

    private fun sign(signingUrl: String) {
        signing.launch(signingUrl)
    }
}
The signing link comes from your server (through one of the server libraries or directly through the API), and no key goes into the app. The result the library reports drives your interface; the event notification on your server is the proof.

What the library covers

  • Show the signing page full screen inside the app, not in an external browser
  • Report the result to the app once: signed · declined · canceled · expired · failed
  • In-session events to update your interface
  • Loading, error and retry screens, dark mode, Arabic right-to-left and English
  • ID attachments, camera and identity verification inside the page
  • No key in the app: your server creates the signing link, and the event notification it receives is the proof

What sets it apart: Activity Result API via WthaiqSigning.Contract() · Jetpack Compose via rememberWthaiqSigningLauncher or WthaiqSigningSheet with the additional com.wthaiq:signing-compose artifact · WthaiqSigningFragment inside your screen · Kotlin or Java · AndroidX dependencies only.

Shared behaviour

One behaviour across the server libraries.

No need to rebuild networking and security logic: the server libraries (PHP · Node.js · Python) implement the following capabilities the same way, for a consistent experience across all your projects.

Safe automatic retries

On connection errors, timeouts and transient responses (429 or 5xx), the library retries with exponential backoff that honours the Retry-After header, and automatically attaches an Idempotency-Key to every POST request and reuses it across its retries, so the same resource is never created twice.

Automatic pagination

Browse thousands of records without managing cursors yourself: the list method returns one page, and the iterator fetches the following pages automatically until the last item.

Verifying the Webhooks signature

A ready-made helper verifies the Wthaiq-Signature header with a constant-time comparison, rejects timestamps older than 300 seconds, and returns the typed event once verified.

Typed errors

API errors become exceptions classified by type: authentication, invalid request, rate limit, conflict and connection; each carries the fields code · param · request_id for quick diagnosis.

Pinning the API version

Every library sends the header Wthaiq-Version: 2026-07-01 pinned on every request, so later changes do not affect your integrations. You can set a different version when you initialise the client.

Configurable timeouts

Set the timeout per attempt and the number of retries per client or per call, cancel a call in Node.js with an AbortSignal, and use your own HTTP client in PHP (PSR-18) or Python (httpx).

And the two in-app signing libraries

— iOS · Android: they show the page and report the result, and carry no key.

No secret key in the app

Your server creates the signing link with its secret key and returns it to the app; the library only shows the page. It accepts only https links on Wthaiq domains and keeps session data in memory by default.

One clear result

The library reports to your app once with one of five results: signed, declined, canceled, expired or failed. That result drives your interface; the proof is the event notification that reaches your server.

Ready for Arabic and dark mode

The library interface runs in Arabic right-to-left or in English, follows the system dark mode, and includes loading, error and retry screens, plus ID attachments, camera and identity verification inside the page.

Versions and support

Policy Clear and stable to upgrade.

We keep the library version separate from the API version and keep changes within predictable limits, so you can plan upgrades with confidence.

SemVer versioning

Every library follows semantic versioning MAJOR.MINOR.PATCH. Breaking changes are only introduced in a new MAJOR version; compatible additions and bug fixes ship safely in MINOR and PATCH releases.

The library version is independent of the API version pinned by the header Wthaiq-Version, so you can upgrade the library without changing API behavior.

A changelog for every library

Every library has a CHANGELOG file in its repository recording what was added and changed in each release, while API changes are dated by the version header and every released version stays supported.

Follow the Changelog to learn early what needs updating.

Minimum runtime versions

The libraryMinimum runtime requirementsPackage sourceVersion
PHPPHP 8.1 or later · curl / json extensionsPackagist · wthaiq/wthaiq-phpAvailable · v1.0.0
Node.jsNode.js 18 or later · TypeScript definitions included · ESM / CommonJSnpm · wthaiqAvailable · v1.0.0
PythonPython 3.10 or later · no required dependenciesPyPI · wthaiqAvailable · v1.0.0
iOSiOS 15 or later · Swift 5.9 or laterSwift Package · WthaiqSigningAvailable · v1.0.0
AndroidAndroid 7.0 (minSdk 24) or later · Kotlin / JavaMaven Central · com.wthaiq:signingAvailable · v1.0.0
The shared foundation: Each server library pins the header Wthaiq-Version: 2026-07-01 by default, and connects tohttps://wthaiq.com/api/v1, and authenticate through Authorization: Bearer sk_.... A live key sk_ actually sends and is billed, while its test version sk_test_ deducts no balance and sends no message to anyone. The two in-app signing libraries carry no key at all.
FAQs

Developer questions About the libraries.

Which languages and platforms are officially supported?

Five official libraries: server libraries (PHP · Node.js · Python) that call the full API, and two in-app signing libraries (iOS · Android) that show the signing page inside your app. The server libraries share the same resource interface and operation names, so what you learn in one language applies to the rest.

Are the libraries open source?

Yes, under the MIT licence on the github.com/wthaiq organization, distributed through the standard package registries: Packagist · npm · PyPI · Swift Package · Maven Central.

How do the server libraries handle retries and safe repetition?

The library retries automatically (twice by default) on connection errors, timeouts and transient responses (429 or 5xx), with exponential backoff that honours the Retry-After header. It attaches an Idempotency-Key to every POST request and reuses it across its retries, so the same resource is never created twice, and you can pass your own key per call.

How do I pin the API version in the library?

The server libraries send the Wthaiq-Version: 2026-07-01 header pinned on every request, so responses keep their shape despite later updates. You can choose another version when you initialise the client, or for a single call after testing it.

What do the in-app signing libraries need from my server?

A signing link that your server creates with one of the server libraries or directly through the API; no key goes into the app. The library shows the page and reports the result to your app once, and the event notification that reaches your server is the final proof.

What are the minimum runtimes and the versioning policy?

PHP: PHP 8.1 or later · curl / json extensions; Node.js: Node.js 18 or later · TypeScript definitions included · ESM / CommonJS; Python: Python 3.10 or later · no required dependencies; iOS: iOS 15 or later · Swift 5.9 or later; Android: Android 7.0 (minSdk 24) or later · Kotlin / Java. All the libraries follow semantic versioning (SemVer): compatible additions in minor releases, and any breaking change in a new major release.

Sign your first document today through the API.

Install your library and follow the quick start guide to create your first signature request in minutes.