Airpdf docs

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.

Spotted a typo or stale claim? Open an issue or ping us in the workspace — docs are versioned with the product.