Four steps with http and crypto — no SDK, no native code. Works on Flutter mobile, web, desktop, and server-side Dart.
Add http for HTTP requests and crypto for HMAC-SHA256. Both are standard Dart/Flutter packages with no native code dependencies.
Exchange client credentials for a bearer token. Cache the token and refresh before the 3600-second expiry. In Flutter, store credentials in flutter_secure_storage — never hardcode them.
Upload the PDF as a multipart request with signer details and field coordinates. The API returns the envelope ID you use to send.
Call /send to dispatch the signing link. When the signer completes, GetSigned POSTs to your server. Verify the HMAC-SHA256 signature with the crypto package before processing.
No. Never embed OAuth2 client credentials in a Flutter app — they can be extracted from the compiled binary. The correct architecture is: your Flutter app calls your own backend API, and your backend calls GetSigned with the credentials stored server-side. The Dart code in this guide is intended for a server-side Dart backend (shelf, dart_frog) or for your backend team to reference. If you need to trigger signing from a Flutter UI, expose an endpoint in your backend that your app calls.
Yes. The http and crypto packages work on all Dart platforms: Flutter (iOS + Android + web + desktop), the Dart CLI, and Dart server runtimes. The multipart upload pattern and HMAC verification are identical across targets. The only platform-specific consideration is where credentials are stored — flutter_secure_storage for Flutter apps (which call your backend), environment variables or a secret manager for Dart server deployments.
MediaType is in the http_parser package, which is a transitive dependency of http — no extra declaration needed in pubspec.yaml. Import it with: import "package:http_parser/http_parser.dart"; If you get a MediaType not found error, add http_parser: ^4.0.0 to your pubspec.yaml explicitly.
Read the raw request body as bytes before any parsing — JSON decoding can alter whitespace and invalidate the HMAC. In shelf: use request.read().toList() to get the byte stream, then Uint8List.fromList(bytes.expand((x) => x).toList()). Extract the X-GetSigned-Signature header, call verifyHmac() with the raw bytes and the header value. Only proceed to parse the JSON payload after the signature is verified.
No dedicated SDK — the integration uses the standard http and crypto packages directly. The full integration is under 100 lines of idiomatic Dart. Using the REST API directly means no SDK version conflicts, no additional transitive dependencies, and no abstraction between your code and the API.
Related: Swift guide · Kotlin guide · Node.js guide · Webhook guide
Free tier — 25 envelopes per month. Full API access from day one.
Get free API keys →