# Get billing data
Source: https://docs.formabledocs.com/api-reference/billing/get-billing-data
/api-reference/openapi.json get /billing
Returns the number of redlining sessions for client
# Create a redline request
Source: https://docs.formabledocs.com/api-reference/endpoint/create-redline-request
POST /redline-requests
Creates a new redline request for a template with specified members. Each member must have an email, displayName, and role. The template must have a DOCX source file available for redlining.
# Create a redline URL
Source: https://docs.formabledocs.com/api-reference/endpoint/create-redline-url
POST /redline-requests/{redlineRequestId}/url
Generates a redline URL for a specific member email associated with a redline request.
The member must already be part of the redline request. API-created URLs use the
embedded path. If it is not that member's turn, an out-of-turn URL is returned instead.
# Create a regular signature request
Source: https://docs.formabledocs.com/api-reference/endpoint/create-regular-signature-request
POST /signature-requests
Creates a signature request for a template with one or more signers and emails each signer a signing link (same delivery path as sharing from the Formable platform).
If template fields have assigned roles, `signers` must include a signer for each of those roles. Requires `signers` (array of email, name, and role, in signing order). Optional `sender` (email and name); when omitted, sender defaults to the API key organization owner. Optionally accepts a `fields` array to pre-fill template fields. You do not need to create signing URLs; Formable emails each signer.
# Create an embedded signature request
Source: https://docs.formabledocs.com/api-reference/endpoint/create-signature-request
POST /signature-requests/embedded
Creates an embedded signature request for a template with one or more signers.
If template fields have assigned roles, `signers` must include a signer for each
of those roles. Requires `signers` (array of email, name, and role, in signing
order). Optional `sender` (email and name); when omitted, sender defaults to the
API key organization owner. Optionally accepts a `fields` array to pre-fill
template fields. Use each signer's `recipientSignatureId` with the create signing
URL endpoint to mint embeddable links.
# Create a signing URL
Source: https://docs.formabledocs.com/api-reference/endpoint/create-signing-url
POST /recipient-signatures/{recipientSignatureId}/url
Generates a signing URL for a specific recipient on a signature request. Use the `recipientSignatureId` returned when creating the signature request. The URL can be used to access the signing interface for that recipient.
# Create a template
Source: https://docs.formabledocs.com/api-reference/endpoint/create-template
POST /templates
Upload a PDF, DOC, or DOCX file to create a new template. The file must be under 40MB.
`signer_roles` is optional. The playground is prefilled with `[{"name":"Client","order":0},{"name":"Witness","order":1}]`. Clear the field if you do not want roles.
# Create a template edit URL
Source: https://docs.formabledocs.com/api-reference/endpoint/create-template-edit-url
POST /templates/{templateId}/edit-url
Generates an edit URL for a template. The URL can be used to access the template editor interface. The client must be authorized to edit the template.
# Get billing data
Source: https://docs.formabledocs.com/api-reference/endpoint/get-billing
GET /billing
Returns the number of redlining sessions for client
# Get a redline request
Source: https://docs.formabledocs.com/api-reference/endpoint/get-redline-request
GET /redline-requests/{redlineRequestId}
Retrieves the redline request by ID
# Get redline request events
Source: https://docs.formabledocs.com/api-reference/endpoint/get-redline-request-events
GET /redline-requests/{redlineRequestId}/events
Retrieves the list of events for a redline request. Requires JWT authentication.
# Get a signature request
Source: https://docs.formabledocs.com/api-reference/endpoint/get-signature-request
GET /signature-requests/{signatureRequestId}
Retrieves the signature request by ID. The response matches create: a `signers`
array (each with `recipientSignatureId`) and envelope `fields` with current
values. Signature image data is never returned; signature fields use
`value: null` and include `signedAt` when signed. Use `status` to poll
progress, `signers` to mint signing URLs, and `fields` to see what has been filled.
# Get signature request events
Source: https://docs.formabledocs.com/api-reference/endpoint/get-signature-request-events
GET /signature-requests/{signatureRequestId}/events
Retrieves the list of events for a signature request. Requires JWT authentication.
# Get a signed envelope
Source: https://docs.formabledocs.com/api-reference/endpoint/get-signed-envelope
GET /signature-requests/{signatureRequestId}/signed-envelope
Retrieves a presigned URL for the signed envelope associated with a signature request. The envelope must be in Completed status.
# Health check
Source: https://docs.formabledocs.com/api-reference/endpoint/health-check
GET /health
Returns the health status of the API server, including uptime and version information. This endpoint does not require authentication.
# List redline requests
Source: https://docs.formabledocs.com/api-reference/endpoint/list-redline-requests
GET /redline-requests
Returns all redline requests for the authenticated client's organization, newest updated first. Optionally pass updatedSince to return only rows with updated_at strictly after that instant (ISO-8601).
# List signature requests
Source: https://docs.formabledocs.com/api-reference/endpoint/list-signature-requests
GET /signature-requests
Returns all signature requests for the authenticated client's organization, newest first. Optionally pass updatedSince to return only rows with updated_at after that instant (ISO-8601).
# Update redline members
Source: https://docs.formabledocs.com/api-reference/endpoint/put-redline-members
PUT /redline-requests/{redlineRequestId}/members
Replaces or upserts the members for an existing redline request. Each member must have an email, displayName, and role. Valid roles are DisclosingParty, ReceivingParty, DisclosingCounsel, ReceivingCounsel.
# Health check endpoint
Source: https://docs.formabledocs.com/api-reference/health/health-check-endpoint
/api-reference/openapi.json get /health
Returns the health status of the API server, including uptime and version information. This endpoint does not require authentication.
# API reference
Source: https://docs.formabledocs.com/api-reference/introduction
REST endpoints for templates, signature requests, and related workflows.
The Formable API is organized around **templates** and **signature requests** for e-signing, with optional **redline request** endpoints for contract negotiation. It's a REST API with predictable, resource-oriented URLs, JSON request and response bodies, and standard HTTP status codes.
Every endpoint page includes a playground. Add your bearer token and send real requests from the docs.
## Base URL
All endpoints are served under `/v1`.
```text theme={null}
https://api.formabledocs.com/v1
```
## Authentication
Every endpoint except the health check requires a Bearer token in the `Authorization` header. Create an API key in [Settings](https://app.formabledocs.com/settings), then pass it on each request. See [Authentication](/authentication) for details.
Prefer a typed client? Use an [official SDK](/sdks/overview) for Node.js, Python, PHP, Java, Go, Ruby, or .NET.
```bash theme={null}
Authorization: Bearer fmbl_YOUR_API_KEY
```
## Response format
Successful responses return JSON with a `200` status. Errors return a JSON object with a single `error` string:
```json theme={null}
{
"error": "templateId is required"
}
```
## Status codes
| Code | Meaning |
| ----- | ---------------------------------------------------------------------------------------------------- |
| `200` | Success. |
| `400` | Bad request — missing or invalid parameters. |
| `401` | Unauthorized — missing or invalid bearer token. |
| `403` | Forbidden — the token is valid but not authorized for this resource. |
| `404` | Not found — the referenced resource doesn't exist. |
| `409` | Conflict — the resource isn't in a valid state (for example, signing an already-completed document). |
| `413` | Payload too large — the uploaded file exceeds 40MB. |
| `500` | Internal server error. |
## Resources
Upload documents and generate editor URLs.
Send documents for e-signature and retrieve signed results.
Create and manage collaborative redline negotiations.
Retrieve usage information.
# Create a redline request
Source: https://docs.formabledocs.com/api-reference/redlining/create-a-redline-request
/api-reference/openapi.json post /redline-requests
Creates a new redline request for a template with specified members. Each member must have an email, displayName, and role. The template must have a DOCX source file available for redlining.
# Create a redline URL for a member
Source: https://docs.formabledocs.com/api-reference/redlining/create-a-redline-url-for-a-member
/api-reference/openapi.json post /redline-requests/{redlineRequestId}/url
Generates a redline URL for a specific member email associated with a redline request.
The member must already be part of the redline request. API-created URLs use the
embedded path. If it is not that member's turn, an out-of-turn URL is returned instead.
# Get a redline request
Source: https://docs.formabledocs.com/api-reference/redlining/get-a-redline-request
/api-reference/openapi.json get /redline-requests/{redlineRequestId}
Retrieves the redline request by ID
# Get redline request events
Source: https://docs.formabledocs.com/api-reference/redlining/get-redline-request-events
/api-reference/openapi.json get /redline-requests/{redlineRequestId}/events
Retrieves the list of events for a redline request. Requires JWT authentication.
# List redline requests
Source: https://docs.formabledocs.com/api-reference/redlining/list-redline-requests
/api-reference/openapi.json get /redline-requests
Returns all redline requests for the authenticated client's organization, newest updated first. Optionally pass updatedSince to return only rows with updated_at strictly after that instant (ISO-8601).
# Update redline request members
Source: https://docs.formabledocs.com/api-reference/redlining/update-redline-request-members
/api-reference/openapi.json put /redline-requests/{redlineRequestId}/members
Replaces or upserts the members for an existing redline request. Each member must have an email, displayName, and role. Valid roles are DisclosingParty, ReceivingParty, DisclosingCounsel, ReceivingCounsel.
# Create a regular signature request
Source: https://docs.formabledocs.com/api-reference/signature-requests/create-a-regular-signature-request
/api-reference/openapi.json post /signature-requests
Creates a signature request for a template with one or more signers and emails each signer a signing link (same delivery path as sharing from the Formable platform).
If template fields have assigned roles, `signers` must include a signer for each of those roles. Requires `signers` (array of email, name, and role, in signing order). Optional `sender` (email and name); when omitted, sender defaults to the API key organization owner. Optionally accepts a `fields` array to pre-fill template fields. You do not need to create signing URLs; Formable emails each signer.
# Create a signing URL for a recipient signature
Source: https://docs.formabledocs.com/api-reference/signature-requests/create-a-signing-url-for-a-recipient-signature
/api-reference/openapi.json post /recipient-signatures/{recipientSignatureId}/url
Generates a signing URL for a specific recipient on a signature request. Use the `recipientSignatureId` returned when creating the signature request. The URL can be used to access the signing interface for that recipient.
# Create an embedded signature request
Source: https://docs.formabledocs.com/api-reference/signature-requests/create-an-embedded-signature-request
/api-reference/openapi.json post /signature-requests/embedded
Creates an embedded signature request for a template with one or more signers.
If template fields have assigned roles, `signers` must include a signer for each
of those roles. Requires `signers` (array of email, name, and role, in signing
order). Optional `sender` (email and name); when omitted, sender defaults to the
API key organization owner. Optionally accepts a `fields` array to pre-fill
template fields. Use each signer's `recipientSignatureId` with the create signing
URL endpoint to mint embeddable links.
# Get a signature request
Source: https://docs.formabledocs.com/api-reference/signature-requests/get-a-signature-request
/api-reference/openapi.json get /signature-requests/{signatureRequestId}
Retrieves the signature request by ID. The response matches create: a `signers`
array (each with `recipientSignatureId`) and envelope `fields` with current
values. Signature image data is never returned; signature fields use
`value: null` and include `signedAt` when signed. Use `status` to poll
progress, `signers` to mint signing URLs, and `fields` to see what has been filled.
# Get a signed envelope for a signature request
Source: https://docs.formabledocs.com/api-reference/signature-requests/get-a-signed-envelope-for-a-signature-request
/api-reference/openapi.json get /signature-requests/{signatureRequestId}/signed-envelope
Retrieves a presigned URL for the signed envelope associated with a signature request. The envelope must be in Completed status.
# Get signature request events
Source: https://docs.formabledocs.com/api-reference/signature-requests/get-signature-request-events
/api-reference/openapi.json get /signature-requests/{signatureRequestId}/events
Retrieves the list of events for a signature request. Requires JWT authentication.
# List signature requests
Source: https://docs.formabledocs.com/api-reference/signature-requests/list-signature-requests
/api-reference/openapi.json get /signature-requests
Returns all signature requests for the authenticated client's organization, newest first. Optionally pass updatedSince to return only rows with updated_at after that instant (ISO-8601).
# Create a template edit URL
Source: https://docs.formabledocs.com/api-reference/templates/create-a-template-edit-url
/api-reference/openapi.json post /templates/{templateId}/edit-url
Generates an edit URL for a template. The URL can be used to access the template editor interface. The client must be authorized to edit the template.
# Create a template from a file upload
Source: https://docs.formabledocs.com/api-reference/templates/create-a-template-from-a-file-upload
/api-reference/openapi.json post /templates
Upload a PDF, DOC, or DOCX file to create a new template. The file must be under 40MB.
# Authentication
Source: https://docs.formabledocs.com/authentication
Authenticate API requests with an API key from Settings.
The Formable API authenticates requests with a Bearer token in the `Authorization` header. Create an API key in [Settings](https://app.formabledocs.com/settings), then send it on every request.
```bash theme={null}
Authorization: Bearer fmbl_YOUR_API_KEY
```
## Get an API key
API keys belong to an organization. Create one in the Formable app, then copy the key when it's shown. For detailed steps, see [Set up a developer account](/developer-account).
Go to [Settings](https://app.formabledocs.com/settings) and create an organization if you don't have one yet. You need an organization before you can generate keys or register webhooks.
In the **API keys** section, click **Generate key**, give it a name, and confirm.
Copy the full key immediately and store it as an environment secret. Formable shows it **once** — after you close the dialog, only a short prefix (for example `fmbl_a1b2c3d4...`) remains visible.
Never expose API keys in browser or mobile code. Call the API from your backend, and only pass short-lived signing and redline URLs to the client.
You can rename or delete keys from the same Settings page. Deleting a key revokes it immediately. Each account can have up to 10 active keys.
## Use the key
Include the key in the `Authorization` header of every API request.
```bash cURL theme={null}
curl --request GET \
--url https://api.formabledocs.com/v1/signature-requests \
--header 'Authorization: Bearer fmbl_YOUR_API_KEY'
```
```javascript Node.js theme={null}
const res = await fetch(
"https://api.formabledocs.com/v1/signature-requests",
{
headers: {
Authorization: `Bearer ${process.env.FORMABLE_API_KEY}`,
},
},
);
```
```python Python theme={null}
import os
import requests
res = requests.get(
"https://api.formabledocs.com/v1/signature-requests",
headers={"Authorization": f"Bearer {os.environ['FORMABLE_API_KEY']}"},
)
```
```php PHP theme={null}
$ch = curl_init('https://api.formabledocs.com/v1/signature-requests');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('FORMABLE_API_KEY'),
],
]);
$res = curl_exec($ch);
```
```java Java theme={null}
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.formabledocs.com/v1/signature-requests"))
.header("Authorization", "Bearer " + System.getenv("FORMABLE_API_KEY"))
.GET()
.build();
HttpResponse res = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
```
```go Go theme={null}
req, _ := http.NewRequest(
http.MethodGet,
"https://api.formabledocs.com/v1/signature-requests",
nil,
)
req.Header.Set("Authorization", "Bearer "+os.Getenv("FORMABLE_API_KEY"))
res, err := http.DefaultClient.Do(req)
```
```ruby Ruby theme={null}
require "net/http"
uri = URI("https://api.formabledocs.com/v1/signature-requests")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch("FORMABLE_API_KEY")}"
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
http.request(request)
end
```
```csharp C# theme={null}
using var client = new HttpClient();
client.DefaultRequestHeaders.Add(
"Authorization",
"Bearer " + Environment.GetEnvironmentVariable("FORMABLE_API_KEY"));
var res = await client.GetAsync("https://api.formabledocs.com/v1/signature-requests");
```
The [Node](/sdks/node), [Python](/sdks/python), [PHP](/sdks/php), [Java](/sdks/java), [Go](/sdks/go), [Ruby](/sdks/ruby), and [.NET](/sdks/dotnet) SDKs send this header for you.
Keys start with `fmbl_`. Treat them like passwords: store them in a secrets manager, rotate by creating a new key and deleting the old one, and never commit them to source control.
## Base URL
```text theme={null}
https://api.formabledocs.com/v1
```
All endpoints are served under this base URL, so a full path looks like `https://api.formabledocs.com/v1/signature-requests`.
## Authorization errors
Requests fail with a `401` when the bearer token is missing, malformed, revoked, or expired:
```json theme={null}
{
"error": "Auth token not valid"
}
```
A `403` means the token is valid but your organization isn't authorized for the resource — for example, creating an edit URL for a template that belongs to another organization.
# Core concepts
Source: https://docs.formabledocs.com/concepts
The key objects and terms you'll work with when embedding e-signatures.
For e-signatures, you upload a reusable **template**, create a **signature request** with one or more signers, mint a **signing URL** per recipient for embedded flows, then download the **signed envelope** when they're done.
## Templates
A **template** is a document you've uploaded (PDF, DOC, or DOCX) with fields placed on it — for example signature, text, date, checkbox, or amount. Templates are reusable: upload once, then create many signature requests from the same `templateId`.
Templates can define **signer roles** (for example `Client` and `Witness`). Assign a role to each required field in the editor. When you create a signature request, every role used by a required field must have a matching signer.
* Create a template with [Create a template](/api-reference/endpoint/create-template).
* Place fields using the **editor URL** returned on creation, or fetch a fresh one with [Create a template edit URL](/api-reference/endpoint/create-template-edit-url).
See the [Embedded templates walkthrough](/walkthroughs/embedded-templates) for the full workflow.
## Signature requests
A **signature request** is one send of a template to one or more signers. You can create a [regular (email) signature request](/api-reference/endpoint/create-regular-signature-request) or an [embedded signature request](/api-reference/endpoint/create-signature-request). Both return a `signatureRequestId` plus a `recipientSignatureId` for each signer.
| Field | Description |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `signers` | People who sign (`email`, `name`, and `role` matching required field roles). Returned on create and [get](/api-reference/endpoint/get-signature-request). |
| `recipientSignatureId` | Per-signer ID on each signer. For embedded flows, use it to mint that person's signing URL. |
| `sender` | Optional. Who is sending (`email` + `name`). Defaults to the API key organization owner. |
| `status` | `Created` when made, `Completed` once signed, or `Expired`. |
| `fields` | Envelope fields on create and get: type, required, filled, current value, and which recipient owns the field. Signature image data is never returned. |
| `testMode` | When `true`, the request doesn't count toward billing. Documents are watermarked and not legally binding. |
For **regular** requests, Formable emails each signer a link — you do not create signing URLs. For **embedded** requests, generate a short-lived **signing URL** from each `recipientSignatureId` and embed it in an iframe. When signing finishes, wait for the [`document_completed`](/webhooks/events#document_completed) webhook, then download the **signed envelope** — a temporary URL to the completed PDF.
[Get a signature request](/api-reference/endpoint/get-signature-request) returns the same `signers` (with `recipientSignatureId`) and `fields` as create, plus the current `status`. Use it to poll progress or recover recipient IDs you didn't persist.
An **envelope** is Formable's internal record of a document prepared for a recipient. As an API consumer you work with signature requests; the signed envelope endpoint is how you get the final PDF.
## Embedded Signing URLs are short-lived and embeddable
Signing URLs are meant to be **embedded in an iframe** in your own product. They expire (typically after one hour), so generate them on demand right before you display them rather than storing them.
Generate signing URLs from your backend and pass them to the client just-in-time. Never expose your API keys in client-side code.
## Test mode
Signature requests accept a `testMode` flag. Use it while integrating so activity doesn't count toward billing. Test mode documents are watermarked and are not legally binding. Test API keys always created test signatures.
## Events
Track signing progress two ways:
* **Push** — configure a [webhook](/webhooks/overview) for real-time events such as `document_viewed`, `document_signed`, and `document_completed`. Wait for `document_completed` before downloading the signed PDF.
* **Pull** — poll [signature request events](/api-reference/endpoint/get-signature-request-events) or check the signature request `status` to reconcile state.
Prefer webhooks for reacting in near real time, and use polling to backfill anything missed.
## Redlining (optional)
[Redlining](/walkthroughs/redlining) is a separate workflow for negotiating a DOCX contract between two parties before signing. It uses **redline requests**, member roles, and turn-based rounds — see that walkthrough when you're ready.
# Set up a developer account
Source: https://docs.formabledocs.com/developer-account
Create a Formable account, organization, API keys, and webhooks so you can call the API: all in less than 5 minutes.
To use the Formable API, create an account, add an organization, then generate an API key. Optionally register a webhook to receive signing and redlining events.
## Create an account
1. Go to [app.formabledocs.com/signup](https://app.formabledocs.com/signup) and create an account.
2. Sign in at [app.formabledocs.com](https://app.formabledocs.com).
3. Open [Settings](https://app.formabledocs.com/settings).
Until you create an organization, API keys and webhooks stay locked.
## Create an organization
API keys, webhooks, and API resources belong to an organization. Each account can have one organization.
In the **Organization** section, click **Create organization**.
Enter a name and click **Create organization**.
Your organization name and ID appear in Settings. **Generate key** and **Register webhook** become available.
## Generate an API key
Use an API key as a Bearer token on every request. See [Authentication](/authentication) for how to send it.
In the **API keys** section, click **Generate key**, enter a name, and confirm.
Formable shows the full key once. Copy it and store it before you click **Done**.
Never expose API keys in browser or mobile code. Call the API from your backend.
You can rename or delete keys from the same page. Deleting a key revokes it immediately. Each account can have up to 10 active keys.
## Register a webhook
Webhooks notify your app when documents are viewed, signed, or updated in a redline workflow. Each organization has one webhook URL. See [Webhooks overview](/webhooks/overview) for delivery details.
In the **Webhooks** section, click **Register webhook**, enter an HTTPS callback URL, and confirm.
Copy the signing secret when it's shown and store it as an environment secret. You'll use it to [verify webhooks](/webhooks/verifying-webhooks). Formable does not show the secret again. You may rotate secrets if need be.
Production callback URLs must use `https://`. After registration you can edit the URL, rotate the secret, or delete the endpoint from the actions menu next to your webhook.
## Next steps
Send your API key on every request.
Create a signature request and get a signing URL.
Typed clients for Node.js, Python, PHP, Java, Go, Ruby, and .NET.
Handle delivery, retries, and event payloads.
Learn how templates and signature requests fit together.
# Formable API
Source: https://docs.formabledocs.com/index
Collect e-signatures with a REST API. Embed signing in your product, or send documents to be signed by email.
The Formable API lets you collect signatures without building the signing experience from scratch. Upload a document once as a **template**, send it as a **signature request**, and get it signed: either inside your product, or by email.
You can try the API without writing code. Open the [API Reference](/api-reference/introduction), add your bearer token on any endpoint page, and send real requests from the docs playground. Building in Node.js, Python, PHP, Java, Go, Ruby, or .NET? Start with the [official SDKs](/sdks/overview).
Create an account, organization, API keys, and webhooks in Settings.
Send your first signature request end to end.
Learn how templates, signature requests, and envelopes fit together.
Typed clients for Node.js, Python, PHP, Java, Go, Ruby, and .NET.
Separate guides for embedded signing and embedded templates.
Prefer a white-glove implementation? Email [matt@formabledocs.com](mailto:matt@formabledocs.com) and we'll handle integrating e-signing in your application for you.
## What you can build
* **Embedded e-signature** — Host signing inside your product via iframe. See [Embedded signing](/walkthroughs/embedded-signing).
* **Templates** — Upload a document and place fields in the editor for your signers to fill.
## How it works
Upload a PDF, DOC, or DOCX with [Create a template](/api-reference/endpoint/create-template). Formable returns a `templateId` you reuse for every send.
Start an [embedded signature request](/api-reference/endpoint/create-signature-request) from the template with `signers`, then generate a [signing URL](/api-reference/endpoint/create-signing-url) for each recipient to embed in your product.
When signing finishes, wait for the [`document_completed`](/webhooks/events#document_completed) webhook, then fetch the [signed envelope](/api-reference/endpoint/get-signed-envelope).
Set up your developer account, then follow the [quickstart](/quickstart) to send your first signature request.
## Also available: redlining
If you need turn-based contract negotiation before signing, Formable also offers an [embedded redlining](/walkthroughs/redlining) walkthrough.
# Adobe Acrobat Sign → Embedded signing
Source: https://docs.formabledocs.com/migrations/adobe-acrobat-sign/embedded-signing
Migrate Adobe Acrobat Sign agreements and signing URLs to the Formable API.
This guide helps you move an Adobe Acrobat Sign embedded signing integration to Formable. You still create a send, mint a signing URL, embed it, and download the completed PDF. You drop OAuth, regional hosts, transient documents on every send, and `OUT_FOR_SIGNATURE` polling in favor of Bearer API keys, template-first sends, and webhook- or poll-driven completion.
If you also prepare library documents or authoring views inside your product, migrate that first with [Adobe Acrobat Sign → Embedded templates](/migrations/adobe-acrobat-sign/embedded-templates). Formable signing always starts from a prepared template.
New to Formable? Complete the [Embedded signing walkthrough](/walkthroughs/embedded-signing) first, then use this page as a translation layer from Acrobat Sign agreements and signing URLs.
Prefer a white-glove migration? Email [matt@formabledocs.com](mailto:matt@formabledocs.com) and we'll handle moving your Adobe Acrobat Sign integration to the Formable API.
## What you're moving
In Adobe Acrobat Sign you typically:
1. Authenticate with OAuth (and often `x-api-user` / on-behalf-of headers) against a regional host such as `api.na1.adobesign.com`
2. Upload a transient document, or reference a library document
3. `POST /agreements` with `participantSetsInfo` and `state: "IN_PROCESS"`
4. Poll until the agreement is `OUT_FOR_SIGNATURE`, then call `GET /agreements/{agreementId}/signingUrls` (or `POST .../views` with a `SIGNING` view)
5. Embed or redirect to the signing URL, detect completion via webhooks or status polling, then download the combined PDF
In Formable you:
1. Authenticate with a Bearer API key (`fmbl_…`)
2. Create an **embedded signature request** from a `templateId` with a `signers` array (each with `email`, `name`, and `role`)
3. Mint a `signingUrl` from each signer's `recipientSignatureId` (no transient document, no regional host, no status wait)
4. Load it in a plain iframe (URL lasts **1 hour**)
5. Handle [`document_completed`](/webhooks/events#document_completed) or poll `status`, then download the signed envelope
The product journey stays the same: prepare a document, send it, embed signing, react when done. The API surface is smaller and organization-scoped by the key.
## Recommended order of work
Create an organization and key in [Settings](https://app.formabledocs.com/settings). See [Authentication](/authentication). You do not need OAuth token exchange for the standard integration.
Re-upload documents and place fields in Formable. If you embed library authoring, follow [Embedded templates migration](/migrations/adobe-acrobat-sign/embedded-templates).
Map participants and merge fields to `signers`, `sender`, and optional `fields`.
Call create signing URL; drop regional hosts and `OUT_FOR_SIGNATURE` polling.
Register one org webhook URL and verify `Content-Sha256`. See [Webhooks](/webhooks/overview).
## What's similar
Several Acrobat Sign ideas transfer directly:
* A reusable **library document / template** still backs many sends.
* You still create a send unit (agreement → **signature request**), then open a short-lived URL for the signer.
* Prefill / merge values still happen at send time; Formable uses `fields: [{ fieldId, value }]`.
* Sandbox / non-production traffic maps to `testMode: true`. Test mode documents are watermarked and are not legally binding.
* After completion you still fetch a combined signed PDF.
If your Acrobat Sign flow is "create agreement → get signing URL → iframe → webhook → download," you are remapping objects and removing transient-document and regional-host bookkeeping, not redesigning the user journey.
## What's different
These Acrobat Sign-specific pieces do not carry over:
| Area | Adobe Acrobat Sign | Formable |
| ------------- | ----------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| Auth | OAuth access token; often `x-api-user` | Bearer `fmbl_…`; no acting-as headers |
| Base URL | Regional (`api.na1.adobesign.com`, etc.) | `https://api.formabledocs.com` |
| Files on send | Transient document or library document on create | Upload a [template](/walkthroughs/embedded-templates) first, then send with `templateId` |
| Ready-to-sign | Poll until `OUT_FOR_SIGNATURE` before signing URLs | Create the request, then mint the URL when ready |
| Signing URL | `GET .../signingUrls` or `POST .../views` (`SIGNING`) | [`POST /v1/recipient-signatures/{id}/url`](/api-reference/endpoint/create-signing-url) |
| Completion UX | Redirect / return URL options on some views | `onSigningComplete` iframe message for UI; confirm with webhooks or polling |
| View TTL | Short-lived signing URLs | **1 hour** |
| Webhooks | Acrobat Sign webhook subscriptions + event names | Org-level URL, `Content-Sha256` |
| Participants | `participantSetsInfo` with `order` / `role` | `signers[]` with `email`, `name`, and `role` |
You no longer upload a transient document per send or wait for Acrobat Sign's async agreement state machine. Create the request when you're ready to send, mint the URL when the user is ready to sign, and listen for completion out of band.
## Concept map
| Adobe Acrobat Sign | Formable | Notes |
| ---------------------------------------- | -------------------------------------------- | ----------------------------------------------------------------------------------- |
| OAuth access token | API key (`Authorization: Bearer fmbl_…`) | No OAuth for the standard integration. |
| Account / `x-api-user` | Organization | Implied by the API key. |
| Agreement | Signature request | Formable's send unit. |
| Participant set member | `signers[]` with `email`, `name`, and `role` | Embedded by default once you mint a `signingUrl`. Save each `recipientSignatureId`. |
| Library document | Template | Prepared once; reused via `templateId`. |
| Transient document | Template upload | Do not re-upload on every send. |
| Signing URL | `signingUrl` | Expires after **1 hour**. |
| `AGREEMENT_WORKFLOW_COMPLETED` / similar | `document_completed` / status `Completed` | Then fetch the signed PDF. |
| Combined document | Signed envelope | Presigned PDF download URL. |
## Endpoint map
| Adobe Acrobat Sign | Formable |
| ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `POST /api/rest/v6/transientDocuments` + `POST /agreements` | Upload a [template](/walkthroughs/embedded-templates), then [`POST /v1/signature-requests/embedded`](/api-reference/endpoint/create-signature-request) |
| `POST /agreements` with `libraryDocumentId` | [`POST /v1/signature-requests/embedded`](/api-reference/endpoint/create-signature-request) with `templateId` |
| `GET /agreements/{id}/signingUrls` | [`POST /v1/recipient-signatures/{id}/url`](/api-reference/endpoint/create-signing-url) |
| `POST /agreements/{id}/views` (`SIGNING`) | [`POST /v1/recipient-signatures/{id}/url`](/api-reference/endpoint/create-signing-url) |
| `GET /agreements/{id}/combinedDocument` | [`GET /v1/signature-requests/{id}/signed-envelope`](/api-reference/endpoint/get-signed-envelope) |
| Webhook subscriptions | Webhook URL in [Settings](https://app.formabledocs.com/settings) |
## Auth
Acrobat Sign:
```bash theme={null}
Authorization: Bearer {access_token}
```
against a regional host such as `https://api.na1.adobesign.com/api/rest/v6/...`, often with `x-api-user`.
Formable:
```bash theme={null}
curl https://api.formabledocs.com/v1/signature-requests \
--header "Authorization: Bearer fmbl_YOUR_API_KEY"
```
One global API host. No `x-api-user`. Create the key in [Settings](https://app.formabledocs.com/settings) and keep it on the server. Full details: [Authentication](/authentication).
## Migrate the flow
### 1. Create the signature request (was: create agreement)
**Adobe Acrobat Sign** (simplified, from a library document):
```json theme={null}
{
"fileInfos": [
{
"libraryDocumentId": "ADOBE_LIBRARY_DOCUMENT_ID"
}
],
"name": "Customer Agreement",
"participantSetsInfo": [
{
"memberInfos": [{ "email": "jane@example.com" }],
"order": 1,
"role": "SIGNER"
}
],
"signatureType": "ESIGN",
"state": "IN_PROCESS",
"mergeFieldInfo": [
{ "fieldName": "company", "defaultValue": "Acme Corporation" }
]
}
```
**Formable:**
```bash theme={null}
curl --request POST \
--url https://api.formabledocs.com/v1/signature-requests/embedded \
--header "Authorization: Bearer $TOKEN" \
--header 'Content-Type: application/json' \
--data '{
"templateId": "abc123xyz",
"signers": [
{ "email": "jane@example.com", "name": "Jane Doe", "role": "SIGNER" }
],
"sender": { "email": "you@yourcompany.com", "name": "Your Company" },
"fields": [
{ "fieldId": "field_company_name", "value": "Acme Corporation" }
],
"testMode": true
}'
```
```json Response theme={null}
{
"signatureRequestId": "sr_456def",
"signers": [
{
"email": "jane@example.com",
"name": "Jane Doe",
"recipientSignatureId": "rsig_789ghi"
}
]
}
```
Pass a `signers` array on every create. Each signer needs `email`, `name`, and `role`. `sender` is optional and defaults to the org owner. Map merge field names to Formable `fieldId`s from the template editor (not Acrobat Sign `fieldName`s). Save each signer's `recipientSignatureId` to mint their signing URL.
| Adobe Acrobat Sign | Formable |
| ------------------------------------------- | ---------------------------------------------------- |
| `libraryDocumentId` | `templateId` |
| `transientDocumentId` on create | Upload a template first; do not attach files on send |
| `participantSetsInfo[].memberInfos[].email` | `signers[].email` / `name` |
| `order` / `role` | `signers[].role` (signing order follows the array) |
| `mergeFieldInfo` | `fields: [{ fieldId, value }]` |
| `state: "IN_PROCESS"` | Create, then mint the URL when ready |
| Sandbox / non-billing testing | `testMode: true` (watermarked, not legally binding) |
### 2. Create the signing URL (was: signingUrls / SIGNING view)
**Adobe Acrobat Sign:**
```bash theme={null}
GET /api/rest/v6/agreements/{agreementId}/signingUrls
```
Often after polling `GET /agreements/{agreementId}` until status is `OUT_FOR_SIGNATURE`.
**Formable:**
```bash theme={null}
curl --request POST \
--url https://api.formabledocs.com/v1/recipient-signatures/rsig_789ghi/url \
--header "Authorization: Bearer $TOKEN"
```
```json Response theme={null}
{
"signingUrl": "https://app.formabledocs.com/sign/embedded/xyz789abc",
"expiresAt": "2024-01-16T10:30:00.000Z"
}
```
No regional host, no `OUT_FOR_SIGNATURE` wait, and no separate views payload. Formable URLs last **1 hour**. Creating a URL for an already completed request returns `409`.
### 3. Embed on the client
```html theme={null}
```
```javascript theme={null}
window.addEventListener("message", (event) => {
if (event.origin !== "https://app.formabledocs.com") return;
if (!event.data || typeof event.data !== "object") return;
if (event.data.type === "onSigningComplete") {
// signer finished — close the iframe or show success
}
});
```
Use `onSigningComplete` for client UX instead of relying only on a return / redirect URL. Confirm completion with [`document_completed`](/webhooks/events#document_completed) or by polling `status` until `Completed` before downloading. See [Embedded signing](/walkthroughs/embedded-signing#detect-completion).
### 4. Download the signed PDF
```bash theme={null}
curl --request GET \
--url https://api.formabledocs.com/v1/signature-requests/sr_456def/signed-envelope \
--header "Authorization: Bearer $TOKEN"
```
```json Response theme={null}
{
"signedEnvelopePresignedUrl": "https://s3.amazonaws.com/bucket/signed-envelope.pdf?..."
}
```
Webhook verification uses `Content-Sha256`. See [Verifying webhooks](/webhooks/verifying-webhooks) and [Webhooks overview](/webhooks/overview).
## Differences to plan for
Drop OAuth token exchange and `x-api-user` headers for a Bearer API key on your server. The organization is implied by the key.
Acrobat Sign often uploads a transient document per agreement. Formable expects a prepared [template](/walkthroughs/embedded-templates) first. Upload once, place fields, then send with `templateId`.
You do not wait for an async agreement state before minting a signing URL. Create the signature request, then call create signing URL when the signer is ready.
Drop regional base URL discovery (`api.na1`, `api.eu1`, and similar). All Formable calls go to `https://api.formabledocs.com`.
Listen for `onSigningComplete` to update the client immediately. Confirm with a webhook or poll before downloading, then build any "signing finished" screen in your own app.
## Checklist
In [Settings](https://app.formabledocs.com/settings).
Or migrate the [embedded template flow](/migrations/adobe-acrobat-sign/embedded-templates) separately.
Use create embedded signature request with `signers` (including `role`), optional `sender`, and optional `fields`.
Call create signing URL with each signer's `recipientSignatureId`; drop regional hosts and `OUT_FOR_SIGNATURE` polling.
Handle `document_completed` and download the signed envelope.
## Next steps
Map library documents and authoring views to Formable.
Full Formable signing walkthrough.
Register endpoints and understand delivery.
Bearer `fmbl_` API keys.
# Adobe Acrobat Sign → Embedded templates
Source: https://docs.formabledocs.com/migrations/adobe-acrobat-sign/embedded-templates
Migrate Adobe Acrobat Sign library documents and authoring views to Formable's upload and editUrl flow.
This guide helps you move Adobe Acrobat Sign library document creation and embedded authoring to Formable. You still upload a document, open an editor for field placement, and reuse a template ID when sending. Formable collapses that into a multipart upload plus an `editUrl` iframe, without OAuth, regional hosts, or transient documents.
When templates are ready, continue with [Adobe Acrobat Sign → Embedded signing](/migrations/adobe-acrobat-sign/embedded-signing) to send documents for signature.
New to Formable? Complete the [Embedded templates walkthrough](/walkthroughs/embedded-templates) first, then use this page as a translation layer from Acrobat Sign library documents and authoring views.
Prefer a white-glove migration? Email [matt@formabledocs.com](mailto:matt@formabledocs.com) and we'll handle moving your Adobe Acrobat Sign integration to the Formable API.
## What you're moving
In Adobe Acrobat Sign apps you typically:
1. `POST /transientDocuments` to upload the file
2. `POST /libraryDocuments` (or create an agreement in `AUTHORING` state) to prepare a reusable document
3. Optionally open an authoring / `EDIT` view (`POST /libraryDocuments/{id}/views` or agreement views) so users place form fields in your product
4. Send agreements from that library document ID, often with `mergeFieldInfo`
In Formable you:
1. `POST /v1/templates` with the file
2. Embed `editUrl` so users place fields in your product
3. Copy each field's `id` for later prefills
4. Create signature requests with that `templateId` and a `signers` array
You are migrating document preparation and in-product editing. Agreement send and signing URLs live on the paired [signing guide](/migrations/adobe-acrobat-sign/embedded-signing).
## Recommended order of work
Create an organization and key in [Settings](https://app.formabledocs.com/settings). See [Authentication](/authentication).
Call [`POST /v1/templates`](/api-reference/endpoint/create-template) with PDF or Word files (max 40MB).
Embed `editUrl` from create, or [`POST .../edit-url`](/api-reference/endpoint/create-template-edit-url) when it expires.
Place fields in the Formable editor and update prefill code to use `fieldId` instead of Acrobat Sign form / merge field names.
Continue with [embedded signing migration](/migrations/adobe-acrobat-sign/embedded-signing).
## What's similar
The high-level template model still matches Acrobat Sign:
* Upload once, get a reusable template ID, send many times.
* Users can edit field placement inside your product via a short-lived editor URL.
* Prefills happen at send time against named field identifiers.
* Template editing and signing use the same auth story on Formable (one Bearer key for both).
If your Acrobat Sign product already embeds an authoring view and stores a library document ID for later agreement creates, keep that product flow. Rebuild how the file is uploaded and how the editor URL is minted.
## What's different
Plan for these Acrobat Sign-specific patterns that do not map 1:1:
| Area | Adobe Acrobat Sign | Formable |
| --------------- | ---------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| Auth | OAuth + regional hosts; often `x-api-user` | Bearer `fmbl_…`; organization from the key |
| Upload path | Transient document, then library document or AUTHORING agreement | One multipart `POST /templates` |
| Field placement | Authoring UI, form field generators, or `PUT .../formFields` | Visual placement in Formable's editor |
| Prefill keys | Form field / merge field names | `fieldId` from the Formable editor |
| Edit view | Library `EDIT` view or agreement authoring view | `editTemplateAccess.editUrl` or `POST .../edit-url` |
| Editor TTL | View expiration from Acrobat Sign | Default about **1 day**; mint just in time |
| Roles on create | Participant sets / roles on library or agreement | Optional `signer_roles` on create; assign roles to fields in the editor; pass `signers[].role` at send time |
Anchor text generators, absolute coordinates in form-field payloads, and per-send AUTHORING agreements do not carry over as the primary path. Recreate positions in the Formable editor, then store the new `fieldId`s in your database or config.
## Concept map
| Adobe Acrobat Sign | Formable | Notes |
| -------------------------------------- | ----------------------------------------------------------------- | ------------------------------------------------ |
| Library document | Template | Upload once, reuse `templateId`. |
| Transient document | File upload on create template | No separate transient ID to manage. |
| Form fields (signature, text, date, …) | Fields (Signature, Text, Date, …) | Placed in Formable's visual editor. |
| Library `EDIT` / authoring view URL | `editUrl` | Embed in an iframe. Expires (default **1 day**). |
| Merge / form field names | `fieldId` | Prefill by ID at signature-request time. |
| Participant roles on the library | Optional `signer_roles` on create + field placement in the editor | Pass matching `signers[].role` at send time. |
## Endpoint map
| Adobe Acrobat Sign | Formable |
| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `POST /transientDocuments` + `POST /libraryDocuments` | [`POST /v1/templates`](/api-reference/endpoint/create-template) |
| `POST /libraryDocuments/{id}/views` (`EDIT`) | [`POST /v1/templates/{templateId}/edit-url`](/api-reference/endpoint/create-template-edit-url) |
| Agreement `AUTHORING` + authoring view | Formable template `editUrl` (prepare once, not per send) |
| `editUrl` / view URL on create | `editTemplateAccess.editUrl` returned from create |
## Auth
Acrobat Sign library APIs sit under regional `/api/rest/v6/...` hosts with an OAuth token. Formable uses the same Bearer key as signing:
```bash theme={null}
curl https://api.formabledocs.com/v1/templates \
--header "Authorization: Bearer fmbl_YOUR_API_KEY" \
--form 'file=@./agreement.pdf' \
--form 'filename=agreement.pdf'
```
See [Authentication](/authentication). Call these endpoints from your backend only.
## Migrate the flow
### 1. Upload the template
**Adobe Acrobat Sign** (simplified):
```bash theme={null}
# 1) Upload transient document
POST /api/rest/v6/transientDocuments
# 2) Create library document from transientDocumentId
POST /api/rest/v6/libraryDocuments
```
**Formable** — one call:
```bash theme={null}
curl --request POST \
--url https://api.formabledocs.com/v1/templates \
--header "Authorization: Bearer $TOKEN" \
--form 'file=@./agreement.pdf' \
--form 'filename=agreement.pdf' \
--form 'signer_roles=[{"name":"SIGNER","order":0}]'
```
```json Response theme={null}
{
"templateId": "abc123xyz",
"editTemplateAccess": {
"editUrl": "https://app.formabledocs.com/template-setup/abc123xyz",
"expiresAt": "2024-01-16T10:30:00.000Z"
}
}
```
There is no separate transient document step. The organization comes from the API key. Supported uploads: PDF, DOCX, and DOC, up to **40MB**. `signer_roles` is optional — pass it as a JSON string in multipart form data when you want named roles before opening the editor. You still assign those roles to required fields in the editor.
### 2. Get a fresh editor URL
When the create URL has expired, or whenever a user needs to edit again:
```bash theme={null}
curl --request POST \
--url https://api.formabledocs.com/v1/templates/abc123xyz/edit-url \
--header "Authorization: Bearer $TOKEN"
```
```json Response theme={null}
{
"editUrl": "https://app.formabledocs.com/template-setup/abc123xyz",
"expiresAt": "2024-01-16T10:30:00.000Z"
}
```
This replaces Acrobat Sign's library `EDIT` view (or agreement authoring view) call. Generate just-in-time on your backend. Unknown IDs return `404`; templates outside your organization return `403`.
### 3. Embed on the client
```html theme={null}
```
Pass only the `editUrl` to the browser — never the API key. Template editing uses the same iframe pattern as [embedded signing](/migrations/adobe-acrobat-sign/embedded-signing). Listen for `onTemplateEditorSaved` when the user finishes editing — see [Embedded templates](/walkthroughs/embedded-templates#listen-for-editor-events).
## Form field → field mapping
| Adobe Acrobat Sign (typical) | Formable field |
| ---------------------------- | -------------- |
| Signature / signature block | Signature |
| Text / full name / company | Text |
| Date / date signed | Date |
| Checkbox | Checkbox |
| Numerical / amount-style | Amount |
If you previously set `mergeFieldInfo` when creating an agreement, use Formable `fields: [{ fieldId, value }]` at [signature request](/migrations/adobe-acrobat-sign/embedded-signing) time instead. Field IDs come from the editor after placement — see [prefills](/walkthroughs/embedded-signing#prefill-fields).
## Differences to plan for
Acrobat Sign separates transient upload from library document create. Formable returns a usable `templateId` and `editUrl` from a single multipart create.
Anchor text generators and coordinate payloads don't carry over as the primary path. Place fields in Formable's editor and reference `fieldId`s for prefills.
Some Acrobat Sign flows author fields on each agreement. Formable templates hold fields; you pass `signers` (with `role`) when creating the signature request.
Template create and edit-url calls use the same Bearer API key as signing — no regional OAuth token or `x-api-user`.
Acrobat Sign form / merge field names won't match Formable `fieldId`s. After users place fields, store the new IDs and update your send payload.
## Checklist
In [Settings](https://app.formabledocs.com/settings).
Call [`POST /v1/templates`](/api-reference/endpoint/create-template).
Embed `editUrl` from create or [`POST .../edit-url`](/api-reference/endpoint/create-template-edit-url).
Place fields in the editor and update prefill code.
Continue with [embedded signing migration](/migrations/adobe-acrobat-sign/embedded-signing).
## Next steps
Map agreements and signing URLs to Formable.
Full Formable template editor walkthrough.
How templates and signature requests fit together.
Bearer `fmbl_` API keys.
# Docusign → Embedded signing
Source: https://docs.formabledocs.com/migrations/docusign/embedded-signing
Migrate Docusign embedded signing (envelopes, recipient views) to the Formable API.
This guide helps you move a Docusign embedded signing integration to Formable. You still create a send, mint a recipient signing URL, embed it, and download the completed PDF. You drop OAuth account paths, `clientUserId`, and `returnUrl` redirects in favor of Bearer API keys, a simpler create payload, and webhook- or poll-driven completion.
If you also prepare templates inside your product, migrate that first with [Docusign → Embedded templates](/migrations/docusign/embedded-templates). Formable signing always starts from a prepared template.
New to Formable? Complete the [Embedded signing walkthrough](/walkthroughs/embedded-signing) first, then use this page as a translation layer from Docusign envelopes and recipient views.
Prefer a white-glove migration? Email [matt@formabledocs.com](mailto:matt@formabledocs.com) and we'll handle moving your Docusign integration to the Formable API.
## What you're moving
In Docusign you typically:
1. Authenticate with OAuth and call account-scoped REST paths
2. Create an envelope with a recipient that has a `clientUserId` (embedded / captive signer)
3. Call `EnvelopeViews:createRecipientView` with matching identity fields plus a `returnUrl`
4. Redirect or iframe the view URL (often \~5 minute TTL)
5. Detect completion via Connect / `eventNotification` or the `returnUrl` query event, then download documents
In Formable you:
1. Authenticate with a Bearer API key (`fmbl_…`)
2. Create an **embedded signature request** from a `templateId` with a `signers` array (each with `email`, `name`, and `role`)
3. Mint a `signingUrl` from each signer's `recipientSignatureId` (no `clientUserId`, no `returnUrl`)
4. Load it in a plain iframe (URL lasts **1 hour**)
5. Handle [`document_completed`](/webhooks/events#document_completed) or poll `status`, then download the signed envelope
The product journey stays the same: prepare a document, send it, embed signing, react when done. The API surface is smaller and organization-scoped by the key rather than by `accountId` in the path.
## Recommended order of work
Create an organization and key in [Settings](https://app.formabledocs.com/settings). See [Authentication](/authentication). You do not need JWT or Authorization Code exchange for the standard integration.
Re-upload documents and place fields in Formable. If you embed template editing, follow [Embedded templates migration](/migrations/docusign/embedded-templates).
Map template roles and tab values to `signers`, `sender`, and optional `fields`.
Call create signing URL; drop `clientUserId`, `returnUrl`, and `authenticationMethod`.
Register one org webhook URL and verify `Content-Sha256`. See [Webhooks](/webhooks/overview).
## What's similar
Several Docusign ideas transfer directly:
* A reusable **template** still backs many sends.
* You still create a send unit (envelope → **signature request**), then open a short-lived URL for the signer.
* Prefill / tab values still happen at send time; Formable uses `fields: [{ fieldId, value }]`.
* Demo / non-billing traffic maps to `testMode: true` (instead of relying only on a demo account). Test mode documents are watermarked and are not legally binding.
* After completion you still fetch a combined signed PDF.
If your Docusign flow is "create envelope from template → create recipient view → iframe → Connect → download," you are remapping objects and removing embedded-signer bookkeeping, not redesigning the user journey.
## What's different
These Docusign-specific pieces do not carry over:
| Area | Docusign | Formable |
| --------------- | ------------------------------------------------------------ | --------------------------------------------------------------------------- |
| Auth | OAuth access token + `/accounts/{accountId}/...` | Bearer `fmbl_…`; no `accountId` in the path |
| Embedded marker | Recipient `clientUserId` | Embedded by default once you mint a `signingUrl` |
| View request | Match email / userName / `clientUserId`; require `returnUrl` | POST create URL with the signer's `recipientSignatureId` |
| Completion UX | Often `returnUrl` redirect with an `event` query param | `onSigningComplete` iframe message for UI; confirm with webhooks or polling |
| View TTL | Commonly \~5 minutes | **1 hour** |
| Webhooks | Connect / `eventNotification`, `X-DocuSign-Signature-1` | Org-level URL, `Content-Sha256` |
| Roles | `templateRoles` / `roleName` | `signers[].role` (match template field roles) |
You no longer maintain a parallel "captive signer" identity. Create the request when you're ready to send, mint the URL when the user is ready to sign, and listen for completion out of band.
## Concept map
| Docusign | Formable | Notes |
| ----------------------------- | -------------------------------------------- | -------------------------------------------------------------------------- |
| OAuth access token | API key (`Authorization: Bearer fmbl_…`) | No JWT / Auth Code for the standard integration. |
| Account (`accountId`) | Organization | Implied by the API key. |
| Envelope | Signature request | Formable's send unit. |
| Recipient + `clientUserId` | `signers[]` with `email`, `name`, and `role` | Embedded by default — no `clientUserId`. Save each `recipientSignatureId`. |
| Recipient view URL | `signingUrl` | Expires after **1 hour** (Docusign \~5 minutes). |
| `returnUrl` | `onSigningComplete` `postMessage` | Close the iframe from the client event; confirm via webhooks or polling. |
| Connect / `eventNotification` | Webhooks | Org-level URL + `Content-Sha256`. |
| Envelope `completed` | `document_completed` / status `Completed` | Then fetch the signed PDF. |
## Endpoint map
| Docusign | Formable |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| `POST /v2.1/accounts/{accountId}/envelopes` | [`POST /v1/signature-requests/embedded`](/api-reference/endpoint/create-signature-request) |
| `POST .../envelopes/{envelopeId}/views/recipient` | [`POST /v1/recipient-signatures/{id}/url`](/api-reference/endpoint/create-signing-url) |
| Get document / combined PDF | [`GET /v1/signature-requests/{id}/signed-envelope`](/api-reference/endpoint/get-signed-envelope) |
| Connect / `eventNotification` | Webhook URL in [Settings](https://app.formabledocs.com/settings) |
## Auth
Docusign:
```bash theme={null}
Authorization: Bearer {access_token}
```
against `/restapi/v2.1/accounts/{accountId}/...`.
Formable:
```bash theme={null}
curl https://api.formabledocs.com/v1/signature-requests \
--header "Authorization: Bearer fmbl_YOUR_API_KEY"
```
No `accountId` in the path. Create the key in [Settings](https://app.formabledocs.com/settings) and keep it on the server. Full details: [Authentication](/authentication).
## Migrate the flow
### 1. Create the signature request (was: create envelope)
**Docusign** (simplified):
```json theme={null}
{
"templateId": "DOCUSIGN_TEMPLATE_ID",
"templateRoles": [
{
"email": "jane@example.com",
"name": "Jane Doe",
"roleName": "Signer",
"clientUserId": "1000",
"tabs": {
"textTabs": [
{ "tabLabel": "company", "value": "Acme Corporation" }
]
}
}
],
"status": "sent"
}
```
**Formable:**
```bash theme={null}
curl --request POST \
--url https://api.formabledocs.com/v1/signature-requests/embedded \
--header "Authorization: Bearer $TOKEN" \
--header 'Content-Type: application/json' \
--data '{
"templateId": "abc123xyz",
"signers": [
{ "email": "jane@example.com", "name": "Jane Doe", "role": "Signer" }
],
"sender": { "email": "you@yourcompany.com", "name": "Your Company" },
"fields": [
{ "fieldId": "field_company_name", "value": "Acme Corporation" }
],
"testMode": true
}'
```
```json Response theme={null}
{
"signatureRequestId": "sr_456def",
"signers": [
{
"email": "jane@example.com",
"name": "Jane Doe",
"recipientSignatureId": "rsig_789ghi"
}
]
}
```
Pass a `signers` array on every create. Each signer needs `email`, `name`, and `role`. `sender` is optional and defaults to the org owner. Map tab / merge values to `fields` using Formable `fieldId`s from the template editor (not Docusign `tabLabel`s). Save each signer's `recipientSignatureId` to mint their signing URL.
| Docusign | Formable |
| -------------------------------- | --------------------------------------------------- |
| `templateId` | `templateId` |
| `templateRoles[].email` / `name` | `signers[].email` / `name` |
| `roleName` | `signers[].role` |
| `clientUserId` | Omit |
| Tab values on the role | `fields: [{ fieldId, value }]` |
| `status: "sent"` | Create, then mint the URL when ready |
| Demo account testing | `testMode: true` (watermarked, not legally binding) |
### 2. Create the signing URL (was: recipient view)
**Docusign:**
```bash theme={null}
POST /v2.1/accounts/{accountId}/envelopes/{envelopeId}/views/recipient
```
```json theme={null}
{
"returnUrl": "https://yourapp.com/signing-complete",
"authenticationMethod": "none",
"email": "jane@example.com",
"userName": "Jane Doe",
"clientUserId": "1000"
}
```
**Formable:**
```bash theme={null}
curl --request POST \
--url https://api.formabledocs.com/v1/recipient-signatures/rsig_789ghi/url \
--header "Authorization: Bearer $TOKEN"
```
```json Response theme={null}
{
"signingUrl": "https://app.formabledocs.com/sign/embedded/xyz789abc",
"expiresAt": "2024-01-16T10:30:00.000Z"
}
```
No `clientUserId`, `returnUrl`, or `authenticationMethod`. You do not re-send the signer's email and name on the URL call — pass their `recipientSignatureId` from the create response. Formable URLs last **1 hour**. Creating a URL for an already completed request returns `409`.
### 3. Embed on the client
```html theme={null}
```
```javascript theme={null}
window.addEventListener("message", (event) => {
if (event.origin !== "https://app.formabledocs.com") return;
if (!event.data || typeof event.data !== "object") return;
if (event.data.type === "onSigningComplete") {
// signer finished — close the iframe or show success
}
});
```
Use `onSigningComplete` instead of a Docusign `returnUrl` redirect for client UX. Confirm completion with [`document_completed`](/webhooks/events#document_completed) or by polling `status` until `Completed` before downloading. See [Embedded signing](/walkthroughs/embedded-signing#detect-completion).
### 4. Download the signed PDF
```bash theme={null}
curl --request GET \
--url https://api.formabledocs.com/v1/signature-requests/sr_456def/signed-envelope \
--header "Authorization: Bearer $TOKEN"
```
```json Response theme={null}
{
"signedEnvelopePresignedUrl": "https://s3.amazonaws.com/bucket/signed-envelope.pdf?..."
}
```
Webhook verification uses `Content-Sha256` instead of `X-DocuSign-Signature-1`. See [Verifying webhooks](/webhooks/verifying-webhooks) and [Webhooks overview](/webhooks/overview).
## Differences to plan for
Drop JWT / Auth Code token exchange for a Bearer API key on your server. The organization is implied by the key, so paths omit `accountId`.
Embedded is the default. Create the request, then mint the URL when the user is ready. You do not mark recipients as captive at create time.
Listen for `onSigningComplete` to update the client immediately. Confirm with a webhook or poll before downloading, then build any "signing finished" screen in your own app.
Plan refresh logic around a **1 hour** TTL instead of Docusign's shorter recipient-view window. Still mint just in time; don't store URLs for later sessions.
## Checklist
In [Settings](https://app.formabledocs.com/settings).
Or migrate the [embedded template flow](/migrations/docusign/embedded-templates) separately.
Use create embedded signature request with `signers` (including `role`), optional `sender`, and optional `fields`.
Call create signing URL with each signer's `recipientSignatureId`; drop `clientUserId`, `returnUrl`, and `authenticationMethod`.
Handle `document_completed` and download the signed envelope.
## Next steps
Map Docusign template edit views to Formable.
Full Formable signing walkthrough.
Register endpoints and understand delivery.
Bearer `fmbl_` API keys.
# Docusign → Embedded templates
Source: https://docs.formabledocs.com/migrations/docusign/embedded-templates
Migrate Docusign embedded template editing to Formable's upload and editUrl flow.
This guide helps you move Docusign template creation and embedded template editing to Formable. You still upload a document, open an editor for field placement, and reuse a `templateId` when sending. Formable collapses that into a multipart upload plus an `editUrl` iframe, without OAuth account paths or Anchor/AutoPlace tabs in the create payload.
When templates are ready, continue with [Docusign → Embedded signing](/migrations/docusign/embedded-signing) to send envelopes for signature.
New to Formable? Complete the [Embedded templates walkthrough](/walkthroughs/embedded-templates) first, then use this page as a translation layer from Docusign templates and template edit views.
Prefer a white-glove migration? Email [matt@formabledocs.com](mailto:matt@formabledocs.com) and we'll handle moving your Docusign integration to the Formable API.
## What you're moving
In Docusign apps you typically:
1. Create or update a template (API and/or web UI) under an account
2. Define tabs with coordinates, anchors, or the sender / template UI
3. Optionally open an embedded template edit view (`TemplateViews:createEdit` and similar) so users adjust fields in your product
4. Send envelopes from that `templateId`, often with `templateRoles` and tab values
In Formable you:
1. `POST /v1/templates` with the file
2. Embed `editUrl` so users place fields in your product
3. Copy each field's `id` for later prefills
4. Create signature requests with that `templateId` and a `signers` array
You are migrating document preparation and in-product editing. Envelope send and recipient views live on the paired [signing guide](/migrations/docusign/embedded-signing).
## Recommended order of work
Create an organization and key in [Settings](https://app.formabledocs.com/settings). See [Authentication](/authentication).
Call [`POST /v1/templates`](/api-reference/endpoint/create-template) with PDF or Word files (max 40MB).
Embed `editUrl` from create, or [`POST .../edit-url`](/api-reference/endpoint/create-template-edit-url) when it expires.
Place fields in the Formable editor and update prefill code to use `fieldId` instead of Docusign `tabLabel` / anchors.
Continue with [embedded signing migration](/migrations/docusign/embedded-signing).
## What's similar
The high-level template model still matches Docusign:
* Upload once, get a reusable template ID, send many times.
* Users can edit field placement inside your product via a short-lived editor URL.
* Prefills happen at send time against named field identifiers.
* Template editing and signing use the same auth story on Formable (one Bearer key for both).
If your Docusign product already embeds a template editor and stores `templateId` for later envelope creates, keep that product flow. Rebuild how the file is uploaded and how the editor URL is minted.
## What's different
Plan for these Docusign-specific patterns that do not map 1:1:
| Area | Docusign | Formable |
| --------------- | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| Auth | OAuth + account-scoped template APIs | Bearer `fmbl_…`; organization from the key |
| Roles on create | Template roles defined up front | Optional `signer_roles` on create; assign roles to fields in the editor; pass `signers[].role` at send time |
| Tab placement | Coordinates, Anchor / AutoPlace strings, or UI | Visual placement in Formable's editor |
| Prefill keys | `tabLabel` / tab groups on roles | `fieldId` from the Formable editor |
| Edit view | Template edit view API with account path | `editTemplateAccess.editUrl` or `POST .../edit-url` |
| Editor TTL | Varies by view | Default about **1 day**; mint just in time |
Anchor strings and absolute coordinates in create-envelope payloads do not carry over. Recreate positions in the Formable editor, then store the new `fieldId`s in your database or config.
## Concept map
| Docusign | Formable | Notes |
| ------------------------------------ | ----------------------------------------------------------------- | --------------------------------------------------- |
| Template | Template | Upload once, reuse `templateId`. |
| Tabs (SignHere, Text, DateSigned, …) | Fields (Signature, Text, Date, …) | Placed in Formable's visual editor. |
| Template edit view URL | `editUrl` | Embed in an iframe. Expires (default **1 day**). |
| Anchor / AutoPlace tabs | Visual placement in the editor | Recreate positions in the UI; prefill by `fieldId`. |
| Template roles | Optional `signer_roles` on create + field placement in the editor | Pass matching `signers[].role` at send time. |
## Endpoint map
| Docusign | Formable |
| ---------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| Create template / upload documents | [`POST /v1/templates`](/api-reference/endpoint/create-template) |
| Template edit view (e.g. `TemplateViews:createEdit`) | [`POST /v1/templates/{templateId}/edit-url`](/api-reference/endpoint/create-template-edit-url) |
| `editUrl` on create | `editTemplateAccess.editUrl` returned from create |
## Auth
Docusign template APIs sit under `/v2.1/accounts/{accountId}/...` with an OAuth token. Formable uses the same Bearer key as signing:
```bash theme={null}
curl https://api.formabledocs.com/v1/templates \
--header "Authorization: Bearer fmbl_YOUR_API_KEY" \
--form 'file=@./agreement.pdf' \
--form 'filename=agreement.pdf'
```
See [Authentication](/authentication). Call these endpoints from your backend only.
## Migrate the flow
### 1. Upload the template
```bash theme={null}
curl --request POST \
--url https://api.formabledocs.com/v1/templates \
--header "Authorization: Bearer $TOKEN" \
--form 'file=@./agreement.pdf' \
--form 'filename=agreement.pdf' \
--form 'signer_roles=[{"name":"Signer","order":0}]'
```
```json Response theme={null}
{
"templateId": "abc123xyz",
"editTemplateAccess": {
"editUrl": "https://app.formabledocs.com/template-setup/abc123xyz",
"expiresAt": "2024-01-16T10:30:00.000Z"
}
}
```
There is no separate OAuth account path. The organization comes from the API key. Supported uploads: PDF, DOCX, and DOC, up to **40MB**. `signer_roles` is optional — pass it as a JSON string in multipart form data when you want named roles before opening the editor. You still assign those roles to required fields in the editor.
### 2. Get a fresh editor URL
When the create URL has expired, or whenever a user needs to edit again:
```bash theme={null}
curl --request POST \
--url https://api.formabledocs.com/v1/templates/abc123xyz/edit-url \
--header "Authorization: Bearer $TOKEN"
```
```json Response theme={null}
{
"editUrl": "https://app.formabledocs.com/template-setup/abc123xyz",
"expiresAt": "2024-01-16T10:30:00.000Z"
}
```
This replaces Docusign's template edit view call. Generate just-in-time on your backend. Unknown IDs return `404`; templates outside your organization return `403`.
### 3. Embed on the client
```html theme={null}
```
Pass only the `editUrl` to the browser — never the API key. Template editing uses the same iframe pattern as [embedded signing](/migrations/docusign/embedded-signing). Listen for `onTemplateEditorSaved` when the user finishes editing — see [Embedded templates](/walkthroughs/embedded-templates#listen-for-editor-events).
## Tab → field mapping
| Docusign tab | Formable field |
| ------------------------- | -------------- |
| SignHere / Signature | Signature |
| Text / FullName / Company | Text |
| DateSigned / Date | Date |
| Checkbox | Checkbox |
| Numerical / amount-style | Amount |
If you previously set tab values on `templateRoles` when creating an envelope, use Formable `fields: [{ fieldId, value }]` at [signature request](/migrations/docusign/embedded-signing) time instead. Field IDs come from the editor after placement — see [prefills](/walkthroughs/embedded-signing#prefill-fields).
## Differences to plan for
Anchor strings and absolute coordinates in the create-envelope payload don't carry over. Place fields in Formable's editor and reference `fieldId`s for prefills.
Docusign templates often define roles up front. Formable supports optional `signer_roles` on template create, but you still assign roles to required fields in the editor and pass matching `signers[].role` when creating the signature request.
Template create and edit-url calls use the same Bearer API key as signing — no account-scoped OAuth token.
Docusign `tabLabel` values won't match Formable `fieldId`s. After users place fields, store the new IDs and update your send payload.
## Checklist
In [Settings](https://app.formabledocs.com/settings).
Call [`POST /v1/templates`](/api-reference/endpoint/create-template).
Embed `editUrl` from create or [`POST .../edit-url`](/api-reference/endpoint/create-template-edit-url).
Place fields in the editor and update prefill code.
Continue with [embedded signing migration](/migrations/docusign/embedded-signing).
## Next steps
Map envelopes and recipient views to Formable.
Full Formable template editor walkthrough.
How templates and signature requests fit together.
Bearer `fmbl_` API keys.
# Dropbox Sign → Embedded signing
Source: https://docs.formabledocs.com/migrations/dropbox-sign/embedded-signing
Migrate Dropbox Sign embedded signing (create_embedded, sign_url) to the Formable API.
This guide helps you move a [Dropbox Sign embedded signing](https://developers.hellosign.com/docs/walkthroughs/embedded-signing) integration to Formable. You keep the same product shape (create a request, mint a URL, embed it) while swapping endpoints, auth, and how you open the signing UI.
If you also embed template setup in your product, migrate that first with [Dropbox Sign → Embedded templates](/migrations/dropbox-sign/embedded-templates). Signing always starts from a prepared Formable template.
New to Formable? Complete the [Embedded signing walkthrough](/walkthroughs/embedded-signing) first, then use this page as a translation layer from Dropbox Sign terms and calls.
Prefer a white-glove migration? Email [matt@formabledocs.com](mailto:matt@formabledocs.com) and we'll handle moving your Dropbox Sign integration to the Formable API.
## What you're moving
In Dropbox Sign you typically:
1. Create an embedded signature request (`create_embedded` or `create_embedded_with_template`)
2. Fetch a per-signer `sign_url` with each `signature_id`
3. Open it with `hellosign-embedded`
4. React to callbacks such as `signature_request_all_signed`, then download files
In Formable you:
1. Upload and prepare a **template** (once, then reuse)
2. Create an **embedded signature request** from that `templateId` with a `signers` array (each signer has `email`, `name`, and `role`)
3. Mint a `signingUrl` from each signer's `recipientSignatureId` and load it in a plain iframe
4. Handle `document_completed` (webhook or poll), then download the signed PDF
The journey is familiar: backend creates the send, backend mints a short-lived URL, frontend embeds it. The main mental shifts are template-first sending, Bearer API keys, and no Dropbox Sign client library.
## Recommended order of work
Create an organization and key in [Settings](https://app.formabledocs.com/settings). See [Authentication](/authentication).
Recreate documents and fields in Formable. If you use embedded templates today, follow [Embedded templates migration](/migrations/dropbox-sign/embedded-templates).
Replace `create_embedded*` and `/embedded/sign_url/{signature_id}` with [`POST /v1/signature-requests/embedded`](/api-reference/endpoint/create-signature-request) and [`POST /v1/recipient-signatures/{id}/url`](/api-reference/endpoint/create-signing-url).
Pass only the `signingUrl` from your backend to the browser.
Register a URL in Settings. See [Webhooks](/webhooks/overview).
## What's similar
Much of the Dropbox Sign model still maps cleanly:
* You still create a **signature request** on the server, then open a short-lived URL in the browser.
* Templates remain the reusable document definition. One template powers many sends.
* `test_mode` / `testMode` keeps integration traffic out of billing. Test mode documents are watermarked and are not legally binding.
* You still download a completed PDF after everyone has signed.
* Signing URLs are meant to be generated **just in time**, not stored long-term. Dropbox Sign `sign_url` values last about 60 minutes and same with Formable `signingUrl`.
Migrating from Dropbox Sign to Formable is almost a 1 to 1 mapping.
## What's different
Plan for these shifts early so you don't recreate Dropbox Sign patterns that Formable doesn't use:
| Area | Dropbox Sign | Formable |
| -------------------- | ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| Auth | API key | API key |
| App / client | API App + `client_id` on requests and in the JS client | Organization implied by the API key; omit `client_id` |
| Files on send | `create_embedded` can attach files inline | Upload a [template](/walkthroughs/embedded-templates) first, then create the signature request |
| Signing URL scope | One `sign_url` per `signature_id` | One `signingUrl` per `recipientSignatureId` |
| Client embed | `hellosign-embedded` + `client.open(...)` | Plain `