Migrating from Adobe Sign
This guide helps you repoint an existing Adobe Acrobat Sign v6 integration at Propper Sign with minimal code changes.
What: Move an Adobe Acrobat Sign v6 integration to Propper Sign.
Why it's straightforward: Propper exposes drop-in, Adobe-compatible v6 endpoints for the four operations most integrations depend on—upload a transient document, create and send an agreement, retrieve an agreement's status, and retrieve a library document. Migrating those calls means changing the base URL and swapping Adobe OAuth for Propper OAuth. The request and response shapes stay the same.
Be deliberate about scope: Only those four operations are Adobe-compatible. Everything else—webhooks, events, bulk send, template authoring, and more—uses the native Propper Sign API. See Feature Parity.
- Importing from Adobe Sign - Bring your existing agreements and library documents into Propper from the web app
- Sign Webhooks - Propper → your backend event notifications
- Sign Quickstart - Send your first agreement with the native Propper Sign API
Who This Guide Is For
This guide is for you if:
- You currently call the Adobe Acrobat Sign REST v6 API from your backend and want to switch to Propper with minimal code changes
- Your integration centers on sending agreements — uploading a document (or reusing a library document), adding participants, sending for signature, and checking status
Overview
Most migrations involve three changes:
- Base URL — Repoint requests from your Adobe Acrobat Sign shard to Propper (
https://api.propper.ai). The/api/rest/v6paths stay the same. - Authentication — Replace your Adobe OAuth access token with a Propper OAuth client-credentials token, sent as a
Bearertoken. - Unsupported surfaces — Anything outside the four Adobe-compatible operations (webhooks, events, bulk send, template authoring, and more) moves to the native Propper Sign API. Plan these as native integrations up front.
Adobe Acrobat Sign serves each account from a specific shard (for example api.na1.adobesign.com), which is why Adobe recommends discovering your access point rather than hardcoding it. Propper serves every account from a single production host, https://api.propper.ai.
Availability
The Adobe Sign compatibility endpoints are enabled per organization. Contact Propper support to enable them for your account. Until they are enabled, the /api/rest/v6 routes respond with a 404 (APPLICATION_NOT_ENTITLED), so a non-enabled account sees exactly what a missing resource would show.
Migration Paths
Choose the approach that fits your situation:
Option A: Hard Cutover
Change the base URL and auth in one deployment. Best for:
- Integrations that only use the four compatible operations
- No in-flight Adobe agreements you need to keep polling from Adobe
- Teams comfortable with a clean break
Option B: Parallel Run
Keep your Adobe Acrobat Sign integration in place while you move new sends to Propper. Best for:
- Larger integrations you want to migrate incrementally
- In-flight Adobe agreements that must complete on Adobe
- Teams that want to validate Propper before a full cutover
During a parallel run, send new agreements through Propper's v6 endpoints while existing Adobe agreements finish on Adobe. To bring historical or in-flight Adobe agreements and library documents into Propper, use Importing from Adobe Sign in the web app.
API Endpoint Mapping
Base URL
| Environment | Adobe Acrobat Sign | Propper |
|---|---|---|
| Production | https://api.{shard}.adobesign.com | https://api.propper.ai |
Compatible Endpoints
Propper implements these four Adobe Acrobat Sign v6 endpoints with the same paths and payload shapes. Repoint the base URL and keep your existing request bodies.
| Operation | Method and Path | Scope | Reference |
|---|---|---|---|
| Upload a transient document | POST /api/rest/v6/transientDocuments | sign:write | Reference |
| Create an agreement | POST /api/rest/v6/agreements | sign:write | Reference |
| Retrieve an agreement | GET /api/rest/v6/agreements/{id} | sign:read | Reference |
| Retrieve a library document | GET /api/rest/v6/libraryDocuments/{id} | sign:read | Reference |
The One-Off Send Flow
A typical Adobe send maps to two calls, exactly as it does on Adobe:
- Upload the document to
POST /transientDocuments. The file is supplied inline as base64 infileInfo.documentBase64(up to 7 MB decoded). You get back a short-livedtransientDocumentId. - Create the agreement with
POST /agreements, referencing that id asfileInfos[0].transientDocumentId, and add participants underparticipantSetsInfo. SetstatetoIN_PROCESSto send immediately (DRAFTandAUTHORINGleave it unsent).
To send from a previously imported reusable document instead, skip step 1 and pass fileInfos[0].libraryDocumentId (see Retrieve a library document). Provide exactly one of transientDocumentId or libraryDocumentId in fileInfos[0].
Authentication Migration
Adobe OAuth → Propper OAuth
Adobe Acrobat Sign integrations authenticate with an Adobe OAuth access token obtained through Adobe's OAuth flow. Propper uses OAuth client credentials: exchange your client ID and secret for a short-lived access token, then send it as a Bearer token on every request.
curl -X POST "https://auth.propper.ai/oauth2/token" \
-H "Content-Type: application/json" \
-d '{
"grant_type": "client_credentials",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"scope": "sign:read sign:write"
}'
The response contains an access_token you send as Authorization: Bearer YOUR_ACCESS_TOKEN. Access tokens expire in one hour—cache and refresh them before expiry. See the Authentication guide for details.
Scope Mapping
Request a Propper token with the scopes your operations need. Both compatible read endpoints require sign:read; both write endpoints require sign:write. A token with sign:read sign:write covers all four.
| Adobe Acrobat Sign scope | Propper scope | Covers |
|---|---|---|
agreement_read | sign:read | Retrieve an agreement |
agreement_write | sign:write | Upload a transient document, create/send an agreement |
library_read | sign:read | Retrieve a library document |
Golden Path Example (End-to-End)
Here is the full one-off send flow—upload, create and send, then check status—in three languages. Replace YOUR_ACCESS_TOKEN with a token from the step above.
- cURL
- JavaScript
- Python
# 1. Upload the document as a transient document
TRANSIENT_ID=$(curl -s -X POST "https://api.propper.ai/api/rest/v6/transientDocuments" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"fileInfo": {
"name": "agreement.pdf",
"documentBase64": "JVBERi0xLjQK..."
}
}' | jq -r '.transientDocumentId')
# 2. Create and send the agreement
AGREEMENT_ID=$(curl -s -X POST "https://api.propper.ai/api/rest/v6/agreements" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"name\": \"Sales Agreement\",
\"state\": \"IN_PROCESS\",
\"fileInfos\": [{ \"transientDocumentId\": \"$TRANSIENT_ID\" }],
\"participantSetsInfo\": [{
\"order\": 1,
\"role\": \"SIGNER\",
\"memberInfos\": [{ \"email\": \"customer@propper.ai\", \"name\": \"Jane Customer\" }]
}]
}" | jq -r '.id')
# 3. Check the agreement status
curl -s -X GET "https://api.propper.ai/api/rest/v6/agreements/$AGREEMENT_ID" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
const BASE_URL = 'https://api.propper.ai/api/rest/v6';
const headers = {
Authorization: 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json',
};
// 1. Upload the document as a transient document
const transientRes = await fetch(`${BASE_URL}/transientDocuments`, {
method: 'POST',
headers,
body: JSON.stringify({
fileInfo: { name: 'agreement.pdf', documentBase64: pdfBase64 },
}),
});
const { transientDocumentId } = await transientRes.json();
// 2. Create and send the agreement
const agreementRes = await fetch(`${BASE_URL}/agreements`, {
method: 'POST',
headers,
body: JSON.stringify({
name: 'Sales Agreement',
state: 'IN_PROCESS',
fileInfos: [{ transientDocumentId }],
participantSetsInfo: [
{
order: 1,
role: 'SIGNER',
memberInfos: [{ email: 'customer@propper.ai', name: 'Jane Customer' }],
},
],
}),
});
const { id: agreementId } = await agreementRes.json();
// 3. Check the agreement status
const statusRes = await fetch(`${BASE_URL}/agreements/${agreementId}`, { headers });
const agreement = await statusRes.json();
console.log(agreement.status); // e.g. "OUT_FOR_SIGNATURE"
import requests
BASE_URL = "https://api.propper.ai/api/rest/v6"
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json",
}
# 1. Upload the document as a transient document
transient = requests.post(
f"{BASE_URL}/transientDocuments",
headers=headers,
json={"fileInfo": {"name": "agreement.pdf", "documentBase64": pdf_base64}},
).json()
transient_id = transient["transientDocumentId"]
# 2. Create and send the agreement
agreement = requests.post(
f"{BASE_URL}/agreements",
headers=headers,
json={
"name": "Sales Agreement",
"state": "IN_PROCESS",
"fileInfos": [{"transientDocumentId": transient_id}],
"participantSetsInfo": [
{
"order": 1,
"role": "SIGNER",
"memberInfos": [{"email": "customer@propper.ai", "name": "Jane Customer"}],
}
],
},
).json()
agreement_id = agreement["id"]
# 3. Check the agreement status
status = requests.get(f"{BASE_URL}/agreements/{agreement_id}", headers=headers).json()
print(status["status"]) # e.g. "OUT_FOR_SIGNATURE"
Agreement Status Values
GET /agreements/{id} returns the agreement's status in Adobe's vocabulary:
| Status | Meaning |
|---|---|
DRAFT | Created but not yet sent |
OUT_FOR_SIGNATURE | Sent and awaiting signatures |
SIGNED | All participants have signed |
CANCELLED | Cancelled by the sender |
DECLINED | A participant declined |
EXPIRED | Expired before completion |
Feature Parity
Adobe-Compatible via the v6 Compatibility Endpoints
| Adobe operation | Propper v6 endpoint | Notes |
|---|---|---|
| Upload transient document | POST /api/rest/v6/transientDocuments | Base64 inline (fileInfo.documentBase64), up to 7 MB decoded |
| Create / send agreement | POST /api/rest/v6/agreements | From a transient or library document; IN_PROCESS sends immediately |
| Retrieve agreement status | GET /api/rest/v6/agreements/{id} | Returns id, name, and status |
| Retrieve library document | GET /api/rest/v6/libraryDocuments/{id} | Returns the reusable document's metadata |
The agreement and library-document reads return core fields only (id, name, status, and metadata). For participant, event, document, or form-field detail, use the native Propper Sign API.
Not Supported via Compatibility — Use the Native Propper Sign API
Everything below is available on Propper, just not through the Adobe-compatible endpoints. Point these at the native Propper Sign API.
| Adobe Sign capability | Use instead |
|---|---|
| Webhooks and events | Propper Webhooks |
| Bulk send | Native agreement and template flows — see the Sign Quickstart |
| Agreement events and audit trail | Native Sign API agreement and audit endpoints |
| Library / template authoring (create, update) | Native Sign templates |
| Reminders, delegation, and participant management post-send | Native Sign API |
| Downloading combined or signed documents | Native Sign API document endpoints |
| Users, groups, and account administration | The Propper dashboard at app.propper.ai |
Error Handling
The v6 compatibility endpoints return Adobe Acrobat Sign's flat error shape, so your existing Adobe error handling keeps working:
{
"code": "AGREEMENT_NOT_FOUND",
"message": "The agreement was not found"
}
| HTTP Status | Code | When |
|---|---|---|
| 400 | MISSING_REQUIRED_PARAM | A required field (for example fileInfo or a participant email) is missing |
| 400 | INVALID_INPUT | The request body failed validation |
| 400 | FILE_TOO_LARGE | The transient document exceeds the 7 MB limit |
| 400 | INVALID_TRANSIENT_DOCUMENT_ID | The referenced transient document was already used |
| 401 | INVALID_ACCESS_TOKEN | The Bearer token is missing, invalid, or expired |
| 403 | PERMISSION_DENIED | The token lacks the required sign:read / sign:write scope |
| 404 | AGREEMENT_NOT_FOUND | No agreement with that id in your organization |
| 404 | LIBRARY_DOCUMENT_NOT_FOUND | No library document with that id in your organization |
| 404 | APPLICATION_NOT_ENTITLED | Adobe Sign compatibility is not enabled for your account |
| 422 | BAD_LIBRARY_DOCUMENT_TYPE | The document is not usable as a reusable library document |
| 502 | MISC_SERVER_ERROR | A transient upstream error — retry shortly |
Testing Checklist
Use this checklist to verify your migration:
- Exchange client credentials for an access token with
scope: "sign:read sign:write" - Upload a transient document and receive a
transientDocumentId - Create an agreement (
state: "IN_PROCESS") and receive anid - Retrieve the agreement and confirm
statusisOUT_FOR_SIGNATURE - Send from a library document via
fileInfos[0].libraryDocumentId - Confirm your error handling reads the flat
{ code, message }shape - Wire remaining surfaces (webhooks, bulk send, events) to the native Propper Sign API
Need Help?
- Importing from Adobe Sign - Bring existing agreements and library documents into Propper from the web app
- Sign Webhooks - Configure Propper outbound event notifications
- Sign Quickstart - Send your first agreement with the native Propper Sign API
- API Reference - Full endpoint documentation
- Support - Contact our migration team