Official SDKs
12 client libraries for the Airpdf Render API. All share the same surface (render, renderAsync, getRender, waitForRender, verifyWebhook) and uniform error model.
Tier 1 — Officially maintained
Hand-crafted, registry-published, full webhook helper, MIT-licensed. Production-ready.
| Language | Package | Min runtime | Install |
|---|---|---|---|
| Node.js / TypeScript |
@airpdf/sdk |
Node 18+ |
npm install @airpdf/sdk |
| Python |
airpdf-sdk |
Python 3.9+ |
pip install airpdf-sdk |
| Go |
github.com/zoonect/airpdf-sdk-go |
Go 1.22+ |
go get github.com/zoonect/airpdf-sdk-go |
| Ruby |
airpdf-sdk |
Ruby 3.0+ |
gem install airpdf-sdk |
Tier 2 — Community / preview
Generated from the OpenAPI spec with hand-written webhook helpers. Breaking changes possible across 0.x. Community PRs welcome.
| Language | Package | Min runtime |
|---|---|---|
| PHP |
airpdf/sdk (Composer) |
PHP 8.1+ |
| .NET / C# |
Airpdf.Sdk (NuGet) |
.NET 8 / .NET Standard 2.1 |
| Java |
it.airpdf:airpdf-sdk (Maven Central) |
Java 17+ |
| Elixir |
airpdf_sdk (Hex) |
Elixir 1.15+ |
Tier 3 — Experimental
Reference implementation in the monorepo; not yet published to package registries. Use cURL or another tier directly until promoted.
| Language | Repo |
|---|---|
| Rust |
github.com/zoonect/airpdf-sdk-rust |
| Kotlin |
github.com/zoonect/airpdf-sdk-kotlin |
| Swift |
github.com/zoonect/airpdf-sdk-swift |
| Dart / Flutter |
github.com/zoonect/airpdf-sdk-dart |
Common surface
Every SDK exposes (names slightly adjusted per language idiom):
| Method | What it does |
|---|---|
render(request) |
Synchronous render. Returns binary PDF bytes or a presigned URL. |
renderAsync(request) |
Enqueues an async render. Returns {id, poll_url} (HTTP 202). |
getRender(id) |
Polls the status of an async render. |
waitForRender(id, options) |
Helper that polls getRender until terminal state. |
verifyWebhook({body, signature, timestamp, secret}) |
HMAC-SHA256 webhook signature check + replay window. |
Error classes
Uniform across all SDKs:
| Class | When | Retry? |
|---|---|---|
AuthError |
401/403 — invalid or revoked API key | No |
QuotaError |
429 — rate limit or monthly quota; carries retryAfter |
After delay |
ClientError |
4xx other — bad request, missing template, schema validation | No (fix payload) |
ServerError |
5xx + network — retryable | Yes (backoff) |
WebhookVerificationError |
Signature/timestamp mismatch | No |
Examples
Node.js / TypeScript
import Airpdf from "@airpdf/sdk";
import { writeFile } from "node:fs/promises";
const client = new Airpdf({ apiKey: process.env.AIRPDF_API_KEY! });
const result = await client.render({
template: "invoice",
data: { customer: { name: "Acme Inc." } },
});
if (result.kind === "binary") {
await writeFile("invoice.pdf", result.pdf);
}
Python
import os
from airpdf import Airpdf
client = Airpdf(api_key=os.environ["AIRPDF_API_KEY"])
result = client.render(
template="invoice",
data={"customer": {"name": "Acme Inc."}},
)
with open("invoice.pdf", "wb") as f:
f.write(result.pdf)
Ruby
require "airpdf"
client = Airpdf::Client.new(api_key: ENV.fetch("AIRPDF_API_KEY"))
result = client.render(
template: "invoice",
data: { customer: { name: "Acme Inc." } }
)
File.binwrite("invoice.pdf", result[:pdf]) if result[:kind] == :binary
Go
import (
"context"
"os"
airpdf "github.com/zoonect/airpdf-sdk-go"
)
client, _ := airpdf.New(os.Getenv("AIRPDF_API_KEY"))
res, _ := client.Render(context.Background(), airpdf.RenderRequest{
Template: "invoice",
Data: map[string]any{"customer": map[string]any{"name": "Acme Inc."}},
})
os.WriteFile("invoice.pdf", res.PDF, 0o644)
Elixir
client = Airpdf.new(api_key: System.fetch_env!("AIRPDF_API_KEY"))
{:ok, %{kind: :binary, pdf: pdf}} =
Airpdf.render(client, template: "invoice", data: %{customer: %{name: "Acme"}})
File.write!("invoice.pdf", pdf)
Async + polling (Node)
const ack = await client.renderAsync({ template: "report", data: {} });
const final = await client.waitForRender(ack.id, { intervalMs: 1000, timeoutMs: 60_000 });
console.log(final.url);
Versioning
All SDKs are released independently. Each starts at 0.1.0. The HTTP API is versioned separately at /api/v1/...; SDK majors track API majors only when breaking changes happen on the wire.
Contributing
Each SDK lives in its own subdirectory of the monorepo with language-native tooling. PRs welcome — see each SDK's README.md for build + test instructions.
License
MIT for every SDK.