URLSession and CryptoKit only — no third-party libraries. Works on iOS, macOS, and server-side Swift. Includes a security note on credential placement.
URLSession handles HTTP and multipart uploads. CryptoKit provides HMAC-SHA256 for webhook verification. Both are built into Apple platforms — add nothing to Package.swift.
Exchange your client credentials for a bearer token. Cache the token and refresh 60 seconds before the 3600-second expiry.
Upload the PDF as a multipart form request with signer details and field coordinates. The response includes the envelope ID you use to send.
Calling /send dispatches the signing link. When signing completes, GetSigned POSTs to your server webhook. Use CryptoKit to verify the HMAC-SHA256 signature.
No. Never embed OAuth2 client credentials in an iOS or macOS app binary — they can be extracted from the IPA. The correct architecture is: your iOS app calls your own backend API, and your backend calls GetSigned with the credentials stored server-side. The Swift code in this guide is intended for server-side Swift (Vapor, Hummingbird) or for your backend team. If you need to trigger signing from an iOS app, expose your own API endpoint that your app calls.
URLSession async/await requires iOS 15+ / macOS 12+. CryptoKit requires iOS 13+ / macOS 10.15+. The multipart body construction works on all platforms with Data and String support. For iOS 14 or earlier, replace async/await with completion handlers using URLSession.dataTask — the HTTP logic is identical.
Yes — the webhook handler works with any Swift HTTP server. The verifyHmac function takes raw body Data and the signature header string, and returns a Bool. In Vapor: read req.body.collect(max:), extract the X-GetSigned-Signature header, and call verifyHmac before parsing the JSON payload. Always read the raw body before deserialization — JSON decoding can change whitespace and break the signature.
No dedicated SDK — the integration uses URLSession and CryptoKit directly. This is intentional: it means there are no third-party dependencies to conflict with your project, no SDK version to track, and no abstraction between you and the API. The full integration is under 120 lines of idiomatic Swift.
Call GET /v1/envelopes/{id}/document with the bearer token. The response body is the sealed PDF as binary data. In URLSession: use URLSession.shared.data(for: request) and write the resulting Data to a file URL with Data.write(to:). In Vapor: stream the response body directly to the client using req.client.get() and Response.body.
Related: Kotlin guide · Java guide · Node.js guide · Webhook guide
Free tier — 25 envelopes per month. Full API access from day one.
Get free API keys →