Skip to main content
developers/donations-sdk/server-sdks
Developer3 min read

Server SDKs

Server-side SDKs in TypeScript / Node and Python. Identical surface across both languages — pick the one that matches your stack.

Server SDKs

The Donations SDK ships server-side SDKs in two languages: TypeScript / Node and Python. They expose the same surface — list donations, fetch a donation, refund, list recurring schedules, cancel a schedule, fire a synthetic webhook — and a constant-time HMAC-SHA256 webhook signature verifier that is byte-compatible across every SDK.

Pick the language that matches your existing stack. There is no functional reason to prefer one over another; we maintain both at full parity.

At a glance

TypeScript / NodePython
Package@1st-flock/donations-embed-nodeonefirstflock-donations-embed
Minimum runtimeNode 18.17Python 3.10
StyleAsync (native fetch)Async (httpx-based)
ModelsPlain typed objectsPydantic v2
Runtime dependenciesNonehttpx, pydantic
Webhook verifierSync, constant-timeSync + async, constant-time

The webhook verifier in every SDK is byte-compatible with the platform's outbound signer, so a signature produced by the platform verifies under any SDK; a signature produced for testing by one SDK verifies under any other.

Common surface

Each SDK provides:

  • A Client (or equivalent) constructed with a secret key (sk_live_… / sk_test_…). Publishable keys are rejected at construction with a clear error.
  • listDonations / list_donations / ListDonations — cursor-paginated.
  • getDonation / get_donation / GetDonation — single donation by UUID.
  • refundDonation / refund_donation / RefundDonation — full or partial; idempotent on Idempotency-Key.
  • listRecurring / list_recurring / ListRecurring — cursor-paginated.
  • cancelRecurring / cancel_recurring / CancelRecurring — idempotent.
  • testWebhook / test_webhook / TestWebhook — fires a synthetic event of any type to your configured endpoint.
  • verifyWebhook / verify_webhook / VerifyWebhook — constant-time HMAC-SHA256 verifier, returns a typed event on success and raises a typed exception on failure.
  • idempotencyKey / idempotency_key / IdempotencyKey — generates a tagged UUID suitable for the Idempotency-Key header.

Common error model

Every SDK raises a typed exception per HTTP status code so caller code can branch on type rather than parsing status codes manually.

HTTPError class
400 / 422ValidationError
401AuthError
403ForbiddenError
404NotFoundError
409ConflictError
410GoneError
429RateLimitError (carries retryAfter / retry_after)
502BadGatewayError
503ServiceUnavailableError
OtherApiError / APIError

All errors expose:

  • HTTP status code
  • A stable machine-readable code from the response body (for example validation_error, card_declined)
  • A human-readable message
  • An optional details object
  • A requestId correlation header value (x-request-id)

Common retry behaviour

Each SDK retries idempotent failures with exponential backoff and jitter. Retries fire on:

  • Network errors (connection refused, DNS failure, timeout)
  • HTTP 502 / 503 / 504

Retries do not fire on 4xx responses (they are caller errors that re-trying will not fix) or on 429 (you must back off based on the Retry-After header). Mutating endpoints (refundDonation, cancelRecurring) require an Idempotency-Key for safe retry; the SDK's idempotencyKey helper generates a tagged UUID suitable for the Idempotency-Key HTTP header.

Pick your language

  • TypeScript / Node — for Node, Bun, Deno (with Node-compat shim), and any other JavaScript-runtime backend.
  • Python — for FastAPI, Django, Flask, Starlette, and any other Python web stack. Async-first; integrates naturally with asyncio and anyio.
Developer Portal