July 2, 2026 · Migration Guide
Migrating from Dropbox Sign (HelloSign) API: A Developer's Guide
Dropbox Sign — the product formerly known as HelloSign — has pushed developers through a rebrand, an OAuth migration, and SDK deprecations. If you're evaluating whether to keep migrating or switch to something simpler, this guide maps every endpoint, webhook, and auth flow side-by-side so you can make the call.
Founder, Signbee
TL;DR
HelloSign became Dropbox Sign. The API got more complex, not simpler. If you're migrating anyway, consider switching to a simpler HelloSign alternative instead of re-implementing OAuth flows and template management. Signbee replaces the entire Dropbox Sign SDK with a single POST /api/v1/send call.
The HelloSign → Dropbox Sign rebrand: what actually changed
HelloSign launched in 2010 as a developer-friendly e-signature API. Dropbox acquired it in 2019 for $230 million, and in 2022 rebranded it to Dropbox Sign. For API users, the rebrand introduced three concrete changes:
1. New base URL. The API moved from api.hellosign.com to api.dropboxsign.com. The old domain still resolves with 301 redirects, but Dropbox has signalled it will be sunset entirely. If your integration relies on the old domain, every request is taking a redirect penalty.
2. OAuth 2.0 enforcement. HelloSign's original API used simple API key authentication — you passed your key as the username in HTTP Basic auth. Dropbox Sign now requires OAuth 2.0 for any integration that accesses accounts on behalf of users. For embedded signing flows, you need to implement the full authorization code grant with PKCE.
3. SDK overhaul. The legacy hellosign-sdk npm package was deprecated. The replacement, @dropbox/sign, is auto-generated from an OpenAPI spec and has a significantly different API surface. Method names, parameter structures, and error handling all changed. If you were using the HelloSign SDK, you are effectively learning a new SDK from scratch.
The net effect: developers who chose HelloSign for its simplicity are now maintaining an integration with the complexity of DocuSign. Many teams use this forced migration as an opportunity to re-evaluate their e-signature API entirely.
Authentication: Dropbox Sign OAuth vs Signbee Bearer auth
This is where the migration pain concentrates. Here's what each flow requires:
| Step | Dropbox Sign OAuth | Signbee Bearer |
|---|---|---|
| 1. Setup | Register app in Dropbox developer console, configure redirect URIs, generate client secret | Copy API key from dashboard |
| 2. Auth flow | Redirect user to consent screen → receive auth code → exchange for access token | Add Bearer token header |
| 3. Token management | Store refresh token, implement token refresh before expiry, handle revocation | No expiry, no refresh |
| 4. Scoping | Request specific OAuth scopes per operation | Full API access with key |
| 5. Error handling | Handle expired tokens, revoked consent, scope errors, redirect mismatches | 401 = bad key |
For server-to-server integrations (the most common use case for e-signature APIs), Dropbox Sign's OAuth adds roughly 200-400 lines of token management code that serves no functional purpose beyond authentication. Signbee eliminates this entirely.
Endpoint mapping: Dropbox Sign → Signbee
Here is a direct mapping of the Dropbox Sign API endpoints you are most likely using to their Signbee equivalents. The key difference: Signbee collapses most of these into a single endpoint with different request body parameters.
| Operation | Dropbox Sign endpoint | Signbee endpoint |
|---|---|---|
| Send for signing | POST /signature_request/send | POST /api/v1/send |
| Send with template | POST /signature_request/send_with_template | POST /api/v1/send (markdown body) |
| Get signature request | GET /signature_request/{id} | GET /api/v1/documents/{id} |
| List requests | GET /signature_request/list | GET /api/v1/documents |
| Cancel request | POST /signature_request/cancel/{id} | DELETE /api/v1/documents/{id} |
| Download signed PDF | GET /signature_request/files/{id} | GET /api/v1/documents/{id}/pdf |
| Create embedded signing | POST /signature_request/create_embedded | POST /api/v1/send (returns signing URL) |
| Get embedded sign URL | GET /embedded/sign_url/{id} | Included in send response |
| Create template | POST /template/create_embedded_draft | N/A (use markdown) |
Notice the pattern: Dropbox Sign requires 9+ endpoints for a standard signing workflow. Signbee uses 3 (/send, /documents, /documents/:id/pdf). Templates are not a separate API resource — they are markdown strings in your codebase, which means they are version-controlled, testable, and do not require a separate dashboard.
Code migration: before and after
Here is a real-world example — sending a document for signature using a template. This is the most common Dropbox Sign API operation.
import * as DropboxSign from "@dropbox/sign";
const signatureRequestApi = new DropboxSign.SignatureRequestApi();
signatureRequestApi.username = "YOUR_ACCESS_TOKEN"; // OAuth token
const signer: DropboxSign.SubSignatureRequestTemplateSigner = {
role: "Client",
emailAddress: "jane@example.com",
name: "Jane Smith",
};
const customField: DropboxSign.SubCustomField = {
name: "project_name",
value: "Website Redesign",
editor: "sender",
required: true,
};
const data: DropboxSign.SignatureRequestSendWithTemplateRequest = {
templateIds: ["tmpl_abc123def456"],
subject: "Service Agreement",
message: "Please review and sign this agreement.",
signers: [signer],
customFields: [customField],
clientId: "YOUR_CLIENT_ID", // Required for embedded
testMode: true,
};
try {
const result = await signatureRequestApi.signatureRequestSendWithTemplate(data);
const signatureRequestId = result.body.signatureRequest?.signatureRequestId;
// Now get the embedded signing URL (separate API call)
const signerId = result.body.signatureRequest?.signatures?.[0]?.signatureId;
const embeddedApi = new DropboxSign.EmbeddedApi();
embeddedApi.username = "YOUR_ACCESS_TOKEN";
const signUrl = await embeddedApi.embeddedSignUrl(signerId!);
console.log("Sign URL:", signUrl.body.embedded?.signUrl);
} catch (error) {
if (error instanceof DropboxSign.HttpError) {
// Handle OAuth token expiry, rate limits, etc.
console.error(error.statusCode, error.body);
}
}const res = await fetch("https://signb.ee/api/v1/send", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_KEY", // No OAuth. No refresh.
},
body: JSON.stringify({
markdown: [
"# Service Agreement",
"",
"**Project:** Website Redesign",
"",
"This agreement confirms that the undersigned agrees to the terms",
"outlined in the attached statement of work.",
"",
"---",
"",
"**Client signature:**",
].join("\n"),
recipient_name: "Jane Smith",
recipient_email: "jane@example.com",
subject: "Service Agreement",
}),
});
const { document_id, signing_url, status } = await res.json();
console.log("Sign URL:", signing_url);
// That's it. No second API call. No SDK. No template dashboard.The Dropbox Sign version requires an SDK import, OAuth token management, template ID lookup, a separate API call for the embedded signing URL, and typed error handling for OAuth edge cases. The Signbee version is a single fetch call. The template is a markdown string — if you need to change the wording, you change a string in your codebase, not a template in a dashboard.
Webhook migration: Dropbox Sign vs Signbee events
Webhook events are where migrations get tricky if you have downstream logic that depends on specific event names or payload shapes. Here is a direct mapping of Dropbox Sign callback events to Signbee webhook events:
| Dropbox Sign event | Signbee event | Notes |
|---|---|---|
signature_request_sent | document.sent | Fired when signing email is delivered |
signature_request_viewed | document.viewed | Recipient opened signing link |
signature_request_signed | document.signed | Signature applied |
signature_request_all_signed | document.completed | PDF and certificate ready for download |
signature_request_declined | document.declined | Signer declined to sign |
signature_request_remind | N/A | Signbee handles reminders automatically |
signature_request_invalid | N/A | Signbee validates at send time, not async |
Key difference: verification. Dropbox Sign uses an API key hash to verify webhook authenticity — you compute an HMAC of the event type using your API key and compare it to the hash in the payload. Signbee uses HMAC-SHA256 with a dedicated webhook secret sent in the X-Signbee-Signature header. The verification logic is simpler and follows the same pattern used by Stripe and GitHub:
// Dropbox Sign: hash-based verification
const crypto = require('crypto');
app.post('/webhook/dropboxsign', (req, res) => {
const eventHash = req.body.event.event_hash;
const eventType = req.body.event.event_type;
const apiKey = process.env.DROPBOX_SIGN_API_KEY;
const computedHash = crypto
.createHmac('sha256', apiKey)
.update(eventType)
.digest('hex');
if (computedHash !== eventHash) {
return res.status(401).send('Invalid signature');
}
// Process event...
res.send('Hello API Event Received'); // Must return this exact string
});// Signbee: HMAC-SHA256, same pattern as Stripe
const crypto = require('crypto');
app.post('/webhook/signbee', (req, res) => {
const signature = req.headers['x-signbee-signature'];
const rawBody = req.rawBody; // Must use raw body, not parsed JSON
const expected = crypto
.createHmac('sha256', process.env.SIGNBEE_WEBHOOK_SECRET)
.update(rawBody)
.digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(rawBody);
// event.type === "document.signed" | "document.completed" | etc.
res.status(200).send('ok');
});Note: Dropbox Sign requires you to return the exact string "Hello API Event Received" in your webhook response. Any other response causes retries. Signbee accepts any 2xx status code, which is the industry standard pattern.
Common migration pitfalls
1. Relying on template IDs
Dropbox Sign templates live in their dashboard and are referenced by opaque IDs (tmpl_abc123). If you have dozens of templates, you need to either recreate them in your new provider's dashboard or, better, move templates into your codebase. Signbee uses markdown strings, so your templates are version-controlled code — no dashboard dependency. Start by exporting your Dropbox Sign template content and converting each to a markdown string.
2. OAuth token refresh race conditions
If you are migrating between two OAuth-based providers, you may have concurrent requests trying to refresh the same token. This causes invalid_grant errors when the first refresh invalidates the old refresh token before the second request can use it. With Signbee's Bearer token auth, this entire class of bugs is eliminated — there are no tokens to refresh.
3. Hardcoded webhook response strings
Dropbox Sign requires the exact string "Hello API Event Received" in webhook responses. If your webhook handler returns a generic 200 OK or a JSON body, Dropbox Sign treats it as a failure and retries. When migrating to Signbee, you can remove this quirk — Signbee accepts any 2xx response.
4. Embedded signing URL expiry
Dropbox Sign embedded signing URLs expire after 60 seconds by default and require a separate API call to generate. If your frontend is slow to render the signing iframe, you can hit expiry errors. Signbee returns the signing URL directly in the send response with a configurable expiry window, eliminating the second API call and the tight timing constraint.
5. Multi-signer ordering assumptions
Dropbox Sign uses a order field on signers to enforce signing order. If you are migrating multi-signer flows, make sure you test the signing order logic in your new provider. Signbee supports sequential signing by sending requests in order via webhooks — when document.signed fires for signer 1, your backend sends to signer 2.
6. File attachment size limits
Dropbox Sign accepts PDF uploads up to 40 MB. If your integration uploads pre-built PDFs, verify that your new provider supports your file sizes. Signbee takes a different approach: you send markdown content and Signbee generates the PDF server-side. This means no file uploads at all for most use cases, which simplifies your API calls and eliminates upload timeout issues.
Migration checklist
grep -r "hellosign\|dropboxsign")"Hello API Event Received" response stringnpm uninstall @dropbox/sign)Frequently Asked Questions
Is the HelloSign API the same as the Dropbox Sign API?
Yes — they are the same product. HelloSign was acquired by Dropbox in 2019 and rebranded in 2022. The base URL changed from api.hellosign.com to api.dropboxsign.com, the SDK was overhauled from hellosign-sdk to @dropbox/sign, and OAuth 2.0 is now required for integrations that access accounts on behalf of users. The old endpoints still work via 301 redirects but are being sunset. If you are evaluating alternatives, see our HelloSign alternative comparison.
What are the best alternatives to the Dropbox Sign API?
For developers prioritising integration speed, Signbee offers a single-endpoint API with Bearer token auth — no OAuth, no SDK, no template dashboard. Other alternatives include BoldSign (API-first with .NET focus), SignWell (API key auth), and PandaDoc (document automation with signing). If you are specifically trying to reduce integration complexity, Signbee and SignWell have the lowest barrier to entry. Read our full developer's guide to e-signature APIs for a detailed comparison.
How long does it take to migrate from Dropbox Sign to Signbee?
Most developers complete the migration in under 2 hours. The steps are: get a Signbee API key (2 minutes), replace API calls with Signbee's single POST endpoint (30 minutes), convert templates to markdown (15-30 minutes), update webhooks (15 minutes), and test end-to-end (15 minutes). The biggest time savings come from eliminating OAuth entirely. If you have complex templates with many merge fields, converting them to markdown is the most time-consuming step. See our webhook events guide for details on setting up Signbee webhooks.
Stop migrating OAuth flows — Bearer token, one endpoint, $0.50/doc.
Last updated: July 7, 2026 · Michael Beckett is the founder of Signbee and B2bee Ltd.