Feature Name: DocuSign eSignature Integration for Document Management & Approvals
Category: AP Excellence (Phase 1) + Compliance & Strategic Finance (Phase 4)
Priority: High
Target Users: CFOs, Controllers, Approvers, Vendors, Steuerberater
Dependencies: AI Approval Intelligence, Document & Contract Management V1, GoBD-Compliant Storage
DocuSign is the world's leading electronic signature platform, offering a comprehensive REST API with 400+ endpoints for programmatic document signing, routing, and tracking. By integrating DocuSign into Orcha, we transform our approval workflow from a digital process to a legally binding, audit-compliant signature system that meets German legal standards (eIDAS, BGB §126a) while dramatically accelerating approval cycles.
Key Value Proposition:
Current State in Orcha: Our AI Approval Intelligence (Phase 1.1) provides:
What's Missing:
The Gap:
1. Purchase Order Approval (Internal)
2. Master Service Agreement Execution (External)
3. Invoice Approval with Signature (Compliance-Heavy)
4. Steuerberater Handoff (Monthly Close)
A bidirectional integration between Orcha and DocuSign that enables:
An envelope is a container for documents requiring signatures.
Envelope
├── Documents (1-n): PDFs, Word docs, etc.
├── Recipients (1-n): Signers, approvers, carbon copies
├── Tabs (fields): Signature boxes, date fields, text fields
├── Routing Order: Sequential or parallel signing
└── Status: Created → Sent → Delivered → Completed
Example:
{
"envelopeId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "sent",
"emailSubject": "Please sign: Purchase Order PO-2024-1234",
"documents": [
{
"documentId": "1",
"name": "PO-2024-1234.pdf",
"order": 1
}
],
"recipients": {
"signers": [
{
"recipientId": "1",
"email": "vendor@acmesupplies.de",
"name": "Johann Schmidt",
"routingOrder": 1
}
]
},
"status": "sent",
"sentDateTime": "2026-01-05T10:30:00Z"
}
Control who signs and in what order.
Recipient Types:
Routing Options:
Orcha Use Case:
Purchase Order Approval Flow:
1. Department Head (Signer) → Approves PO
2. CFO (Signer, if > €10K) → Additional approval
3. Vendor (Signer) → Acknowledges terms
4. AP Team (CC) → Receives final signed copy
Reusable document templates with predefined fields.
Benefits:
Orcha Templates:
Example:
{
"templateId": "t1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Purchase Order Approval",
"documents": [
{
"name": "Standard PO",
"fileExtension": "pdf",
"order": 1
}
],
"recipients": {
"signers": [
{
"roleName": "Department Head",
"routingOrder": 1,
"tabs": {
"signHereTabs": [
{
"anchorString": "/dept_sig/",
"anchorXOffset": "0",
"anchorYOffset": "0"
}
]
}
},
{
"roleName": "Vendor",
"routingOrder": 2,
"tabs": {
"signHereTabs": [
{
"anchorString": "/vendor_sig/",
"anchorXOffset": "0",
"anchorYOffset": "0"
}
]
}
}
]
}
}
Interactive elements placed on documents.
Common Tab Types:
Anchor-Based Positioning: Instead of pixel coordinates, use text anchors:
{
"signHereTabs": [
{
"anchorString": "Authorized Signature:",
"anchorXOffset": "100",
"anchorYOffset": "-5"
}
]
}
Real-time event notifications.
Key Events:
envelope-sent: Envelope sent to recipientsenvelope-delivered: Recipient opened envelopeenvelope-completed: All signatures collectedenvelope-declined: Recipient rejectedenvelope-voided: Sender canceledrecipient-completed: Individual signer finishedOrcha Webhook Handler:
(defn docusign-webhook-handler
[request]
(let [event (parse-docusign-event (:body request))
envelope-id (:envelopeId event)
status (:status event)]
(case status
"completed" (handle-completed-envelope envelope-id)
"declined" (handle-declined-envelope envelope-id)
"voided" (handle-voided-envelope envelope-id)
(log-event event))))
(defn handle-completed-envelope
[envelope-id]
;; 1. Fetch signed document from DocuSign
(let [signed-doc (fetch-signed-document envelope-id)]
;; 2. Store in Orcha GoBD-compliant storage
(store-document signed-doc {:type :signed-contract
:docusign-envelope envelope-id})
;; 3. Update approval status in database
(update-approval-status envelope-id :completed)
;; 4. Trigger downstream workflows (e.g., activate PO)
(activate-purchase-order envelope-id)))
Authorization Code Grant (Recommended for Orcha):
GET https://account.docusign.com/oauth/auth
?response_type=code
&scope=signature impersonation
&client_id=YOUR_INTEGRATION_KEY
&redirect_uri=https://orcha.com/oauth/callback
POST https://account.docusign.com/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=AUTHORIZATION_CODE
&client_id=YOUR_INTEGRATION_KEY
&client_secret=YOUR_SECRET_KEY
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"token_type": "Bearer",
"expires_in": 28800,
"refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGc..."
}
Token Storage in Orcha:
CREATE TABLE docusign_tokens (
user_id UUID PRIMARY KEY REFERENCES users(id),
access_token TEXT NOT NULL,
refresh_token TEXT NOT NULL,
expires_at TIMESTAMP NOT NULL,
account_id TEXT NOT NULL,
base_uri TEXT NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
Endpoint: POST /v2.1/accounts/{accountId}/envelopes
Request:
{
"emailSubject": "Please sign: Purchase Order PO-2024-1234",
"status": "sent",
"documents": [
{
"documentBase64": "JVBERi0xLjQKJeLjz9MKMy...",
"name": "PO-2024-1234.pdf",
"fileExtension": "pdf",
"documentId": "1"
}
],
"recipients": {
"signers": [
{
"email": "dept.head@company.de",
"name": "Maria Weber",
"recipientId": "1",
"routingOrder": "1",
"tabs": {
"signHereTabs": [
{
"anchorString": "/dept_sig/",
"anchorXOffset": "0",
"anchorYOffset": "0"
}
],
"dateSignedTabs": [
{
"anchorString": "/date/",
"anchorXOffset": "0",
"anchorYOffset": "0"
}
]
}
}
]
}
}
Response:
{
"envelopeId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "sent",
"uri": "/envelopes/a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
Endpoint: POST /v2.1/accounts/{accountId}/envelopes
Request:
{
"templateId": "t1b2c3d4-e5f6-7890-abcd-ef1234567890",
"templateRoles": [
{
"roleName": "Department Head",
"name": "Maria Weber",
"email": "maria.weber@company.de",
"tabs": {
"textTabs": [
{
"tabLabel": "PO_Number",
"value": "PO-2024-1234"
},
{
"tabLabel": "Amount",
"value": "€8,450.00"
}
]
}
},
{
"roleName": "Vendor",
"name": "Johann Schmidt",
"email": "johann@acmesupplies.de"
}
],
"status": "sent"
}
Endpoint: GET /v2.1/accounts/{accountId}/envelopes/{envelopeId}
Response:
{
"envelopeId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "completed",
"statusChangedDateTime": "2026-01-05T14:22:15Z",
"emailSubject": "Please sign: Purchase Order PO-2024-1234",
"recipients": {
"signers": [
{
"email": "maria.weber@company.de",
"name": "Maria Weber",
"status": "completed",
"signedDateTime": "2026-01-05T11:15:30Z"
},
{
"email": "johann@acmesupplies.de",
"name": "Johann Schmidt",
"status": "completed",
"signedDateTime": "2026-01-05T14:22:10Z"
}
]
}
}
Endpoint: GET /v2.1/accounts/{accountId}/envelopes/{envelopeId}/documents/{documentId}
Headers:
Authorization: Bearer {access_token}
Accept: application/pdf
Response: Binary PDF data
Orcha Implementation:
(defn download-signed-document
[account-id envelope-id document-id]
(let [url (str "https://demo.docusign.net/restapi/v2.1/accounts/"
account-id "/envelopes/" envelope-id
"/documents/" document-id)
response (http/get url
{:headers {"Authorization" (str "Bearer " (get-access-token))
"Accept" "application/pdf"}
:as :byte-array})]
(:body response)))
Endpoint: GET /v2.1/accounts/{accountId}/envelopes/{envelopeId}/documents/certificate
Response: PDF with complete audit trail including:
GoBD Compliance: This certificate is legally recognized in Germany for audit purposes.
Endpoint: PUT /v2.1/accounts/{accountId}/envelopes/{envelopeId}
Request:
{
"status": "voided",
"voidedReason": "Purchase order canceled by department head"
}
┌──────────────────────────────────────────────────────────────────┐
│ ORCHA PLATFORM │
├──────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ AI APPROVAL INTELLIGENCE │ │
│ │ (Existing Phase 1.1) │ │
│ │ │ │
│ │ • 4-way match validation │ │
│ │ • AI explainability │ │
│ │ • Decision consequences │ │
│ │ • Policy checks │ │
│ └─────────────────┬──────────────────────────────────────┘ │
│ │ │
│ │ Approval decision made │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ DOCUSIGN INTEGRATION SERVICE (NEW) │ │
│ ├────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ 📤 OUTBOUND │ │
│ │ ├─ Create envelope from document │ │
│ │ ├─ Create envelope from template │ │
│ │ ├─ Add recipients & routing rules │ │
│ │ ├─ Position signature tabs │ │
│ │ └─ Send for signature │ │
│ │ │ │
│ │ 📥 INBOUND │ │
│ │ ├─ Receive webhook events │ │
│ │ ├─ Download signed documents │ │
│ │ ├─ Fetch audit trail (Certificate of Completion) │ │
│ │ └─ Update Orcha approval status │ │
│ │ │ │
│ │ 🔄 STATUS TRACKING │ │
│ │ ├─ Real-time status dashboard │ │
│ │ ├─ Reminder automation │ │
│ │ └─ Escalation workflows │ │
│ │ │ │
│ └─────────────────┬──────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ DOCUMENT MANAGEMENT (Existing Phase 1.2) │ │
│ │ │ │
│ │ • GoBD-compliant storage │ │
│ │ • Immutable audit trail │ │
│ │ • Version control │ │
│ │ • Search & retrieval │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────┘
↕ HTTPS (OAuth 2.0)
┌──────────────────────────────────────────────────────────────────┐
│ DOCUSIGN eSignature REST API │
├──────────────────────────────────────────────────────────────────┤
│ │
│ • 400+ API Endpoints │
│ • Envelope Management │
│ • Template Management │
│ • Recipient Routing │
│ • Webhook Events (DocuSign Connect) │
│ • Certificate of Completion (Audit Trail) │
│ • eIDAS Compliance (EU) │
│ │
└──────────────────────────────────────────────────────────────────┘
↕
┌──────────────────────────────────────────────────────────────────┐
│ RECIPIENTS │
├──────────────────────────────────────────────────────────────────┤
│ │
│ • Department Heads (Internal) │
│ • CFO / Controllers (Internal) │
│ • Vendors (External) │
│ • Steuerberater (External) │
│ • External Auditors (External) │
│ │
└──────────────────────────────────────────────────────────────────┘
-- DocuSign Configuration
CREATE TABLE docusign_config (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES tenants(id),
integration_key TEXT NOT NULL,
secret_key_encrypted TEXT NOT NULL,
account_id TEXT NOT NULL,
base_uri TEXT NOT NULL,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- DocuSign Tokens (per user)
CREATE TABLE docusign_tokens (
user_id UUID PRIMARY KEY REFERENCES users(id),
access_token TEXT NOT NULL,
refresh_token TEXT NOT NULL,
expires_at TIMESTAMP NOT NULL,
account_id TEXT NOT NULL,
base_uri TEXT NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Templates
CREATE TABLE docusign_templates (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES tenants(id),
template_id TEXT NOT NULL, -- DocuSign template ID
name TEXT NOT NULL,
description TEXT,
document_type TEXT NOT NULL, -- 'purchase_order', 'contract', 'invoice_approval', etc.
roles JSONB NOT NULL, -- Array of role definitions
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Envelopes
CREATE TABLE docusign_envelopes (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES tenants(id),
envelope_id TEXT NOT NULL UNIQUE, -- DocuSign envelope ID
-- Link to Orcha entities
approval_id UUID REFERENCES approvals(id),
invoice_id UUID REFERENCES invoices(id),
purchase_order_id UUID REFERENCES purchase_orders(id),
contract_id UUID REFERENCES contracts(id),
-- Envelope details
template_id UUID REFERENCES docusign_templates(id),
subject TEXT NOT NULL,
status TEXT NOT NULL, -- 'created', 'sent', 'delivered', 'completed', 'declined', 'voided'
-- Recipients
recipients JSONB NOT NULL, -- Array of recipient objects
-- Documents
documents JSONB NOT NULL, -- Array of document metadata
-- Audit trail
sent_at TIMESTAMP,
delivered_at TIMESTAMP,
completed_at TIMESTAMP,
voided_at TIMESTAMP,
voided_reason TEXT,
-- Signed document storage
signed_document_url TEXT, -- S3 URL
certificate_url TEXT, -- Certificate of Completion URL
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_envelopes_status ON docusign_envelopes(status);
CREATE INDEX idx_envelopes_approval_id ON docusign_envelopes(approval_id);
CREATE INDEX idx_envelopes_invoice_id ON docusign_envelopes(invoice_id);
-- Envelope Events (from webhooks)
CREATE TABLE docusign_envelope_events (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
envelope_id TEXT NOT NULL REFERENCES docusign_envelopes(envelope_id),
event_type TEXT NOT NULL, -- 'sent', 'delivered', 'completed', 'declined', 'voided', etc.
recipient_email TEXT,
recipient_name TEXT,
status TEXT,
ip_address INET,
user_agent TEXT,
timestamp TIMESTAMP NOT NULL,
raw_payload JSONB NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_envelope_events_envelope ON docusign_envelope_events(envelope_id);
CREATE INDEX idx_envelope_events_type ON docusign_envelope_events(event_type);
Flow:
1. Department Head creates PO in Orcha
2. Orcha AI validates PO (budget check, policy compliance)
3. PO requires signature → Orcha creates DocuSign envelope
4. DocuSign sends PO to:
a. Department Head (signer, routing order 1)
b. CFO (signer, routing order 2, if > €10K)
c. Vendor (signer, routing order 3)
5. Recipients sign in sequence
6. DocuSign webhook → Orcha: "envelope completed"
7. Orcha downloads signed PO
8. Orcha stores in GoBD-compliant storage
9. Orcha activates PO (now legally binding)
10. Invoice matching can proceed against signed PO
Value:
UI in Orcha:
┌────────────────────────────────────────────────────────────────┐
│ PURCHASE ORDER PO-2024-1234 │
├────────────────────────────────────────────────────────────────┤
│ │
│ Status: Pending Signatures (2 of 3 completed) │
│ │
│ ✅ Maria Weber (Dept Head) - Signed Jan 5, 11:15 AM │
│ ✅ Klaus Müller (CFO) - Signed Jan 5, 11:42 AM │
│ ⏳ Johann Schmidt (Vendor) - Sent Jan 5, 11:45 AM │
│ │
│ [View Document] [Send Reminder] [Cancel Envelope] │
│ │
└────────────────────────────────────────────────────────────────┘
Scenario: CFO negotiates annual contract with office supplies vendor (€250K/year spend).
Flow:
1. CFO uploads MSA draft to Orcha
2. Legal review (internal or external)
3. CFO clicks "Send for Signature" in Orcha
4. Orcha creates DocuSign envelope from MSA Template
5. Sequential routing:
a. CFO (signer, routing order 1)
b. Vendor Legal (signer, routing order 2)
c. Vendor CFO (signer, routing order 3)
6. All parties sign electronically
7. Signed MSA returned to Orcha
8. Orcha extracts contract terms (pricing, volume discounts, payment terms)
9. Contract terms feed into invoice validation rules
10. Procurement Intelligence monitors compliance
Value:
Orcha + DocuSign + AI:
Signed MSA → AI extracts terms → Contract compliance rules
Example:
"Vendor X must provide 2% early payment discount for payment within 10 days"
→ Orcha automatically flags invoices without discount
→ AP team follows up with vendor
Scenario: German compliance requirements for large expenditures.
Flow:
1. Invoice arrives (€75K for IT equipment)
2. Orcha AI validates:
✓ 4-way match (invoice ↔ PO ↔ GR ↔ contract)
✓ Budget available
✓ No fraud signals
3. Orcha: "This invoice requires CFO signature (amount > €50K)"
4. Orcha creates DocuSign envelope with:
- Original invoice PDF
- 4-way match report
- Budget impact summary
5. CFO receives email with full context
6. CFO signs electronically
7. Signed approval returned to Orcha
8. Orcha posts to GL and schedules payment
Value:
Scenario: German GoBD requires period locking with authorized signature.
Flow:
1. Controller completes month-end close in Orcha
2. All transactions reconciled (AP, bank, GL)
3. Controller clicks "Finalize Period" → Orcha creates envelope
4. Sequential routing:
a. Controller (signer, routing order 1)
b. CFO (signer, routing order 2)
c. Steuerberater (CC, routing order 3)
5. Controller and CFO sign Festschreibung certificate
6. Steuerberater receives signed certificate + DATEV export
7. Period locked in Orcha (no further edits)
Value:
Scenario: Dynamic discounting (Phase 3.2) - vendor requests early payment.
Flow:
1. Vendor logs into Orcha vendor portal
2. Vendor sees unpaid invoices (€45K due in 25 days)
3. Vendor clicks "Request Early Payment"
4. Vendor offers 2% discount for payment in 5 days
5. Orcha calculates APR: 2% for 20 days = 36% APR
6. Orcha creates DocuSign envelope:
- Early payment agreement
- Amended invoice with discount
7. Routing:
a. Vendor (signer, confirms discount offer)
b. Orcha Treasurer (signer, accepts offer)
8. Both parties sign → Payment scheduled for day 5
9. Vendor receives payment early, Orcha saves €900
Value:
Deliverables:
Code Example: OAuth Flow
(ns orcha.docusign.auth
(:require [clj-http.client :as http]
[cheshire.core :as json]
[orcha.config :refer [config]]
[orcha.db.docusign :as db]))
(def auth-base-url "https://account.docusign.com")
(def api-base-url "https://demo.docusign.net/restapi")
(defn get-authorization-url
"Generate DocuSign OAuth authorization URL"
[redirect-uri state]
(str auth-base-url "/oauth/auth"
"?response_type=code"
"&scope=signature%20impersonation"
"&client_id=" (:docusign-integration-key config)
"&redirect_uri=" redirect-uri
"&state=" state))
(defn exchange-code-for-token
"Exchange authorization code for access token"
[code]
(let [response (http/post (str auth-base-url "/oauth/token")
{:form-params {:grant_type "authorization_code"
:code code
:client_id (:docusign-integration-key config)
:client_secret (:docusign-secret-key config)}
:content-type :x-www-form-urlencoded
:as :json})]
(:body response)))
(defn refresh-access-token
"Refresh expired access token"
[refresh-token]
(let [response (http/post (str auth-base-url "/oauth/token")
{:form-params {:grant_type "refresh_token"
:refresh_token refresh-token
:client_id (:docusign-integration-key config)
:client_secret (:docusign-secret-key config)}
:content-type :x-www-form-urlencoded
:as :json})]
(:body response)))
(defn get-user-info
"Fetch DocuSign user info (includes account ID and base URI)"
[access-token]
(let [response (http/get (str auth-base-url "/oauth/userinfo")
{:headers {"Authorization" (str "Bearer " access-token)}
:as :json})]
(:body response)))
(defn store-tokens
"Store access and refresh tokens for user"
[user-id token-response]
(let [user-info (get-user-info (:access_token token-response))
account (first (:accounts user-info))
expires-at (java.time.Instant/ofEpochSecond
(+ (System/currentTimeMillis) (* (:expires_in token-response) 1000)))]
(db/upsert-token {:user-id user-id
:access-token (:access_token token-response)
:refresh-token (:refresh_token token-response)
:expires-at expires-at
:account-id (:account_id account)
:base-uri (:base_uri account)})))
(defn get-valid-token
"Get valid access token for user (refresh if expired)"
[user-id]
(let [token (db/get-token user-id)]
(if (and token (> (.getEpochSecond (:expires-at token))
(System/currentTimeMillis)))
(:access-token token)
(let [refreshed (refresh-access-token (:refresh-token token))]
(store-tokens user-id refreshed)
(:access_token refreshed)))))
Code Example: Create Envelope
(ns orcha.docusign.envelopes
(:require [clj-http.client :as http]
[cheshire.core :as json]
[clojure.java.io :as io]
[orcha.docusign.auth :as auth]
[orcha.db.docusign :as db]
[orcha.storage :as storage]))
(defn create-envelope
"Create and send DocuSign envelope"
[{:keys [user-id document-url subject recipients template-id template-data]}]
(let [token (auth/get-valid-token user-id)
token-info (db/get-token user-id)
account-id (:account-id token-info)
base-uri (:base-uri token-info)
;; Download document if URL provided
document-base64 (when document-url
(-> (storage/download document-url)
(java.util.Base64/getEncoder)
(.encodeToString)))
;; Build envelope definition
envelope-def (if template-id
;; Template-based envelope
{:templateId template-id
:templateRoles recipients
:status "sent"}
;; Document-based envelope
{:emailSubject subject
:documents [{:documentBase64 document-base64
:name "document.pdf"
:fileExtension "pdf"
:documentId "1"}]
:recipients {:signers recipients}
:status "sent"})
response (http/post (str base-uri "/v2.1/accounts/" account-id "/envelopes")
{:headers {"Authorization" (str "Bearer " token)
"Content-Type" "application/json"}
:body (json/generate-string envelope-def)
:as :json})]
(:body response)))
(defn get-envelope-status
"Fetch envelope status from DocuSign"
[user-id envelope-id]
(let [token (auth/get-valid-token user-id)
token-info (db/get-token user-id)
account-id (:account-id token-info)
base-uri (:base-uri token-info)
response (http/get (str base-uri "/v2.1/accounts/" account-id
"/envelopes/" envelope-id)
{:headers {"Authorization" (str "Bearer " token)}
:as :json})]
(:body response)))
(defn download-completed-document
"Download signed document from DocuSign"
[user-id envelope-id document-id]
(let [token (auth/get-valid-token user-id)
token-info (db/get-token user-id)
account-id (:account-id token-info)
base-uri (:base-uri token-info)
response (http/get (str base-uri "/v2.1/accounts/" account-id
"/envelopes/" envelope-id
"/documents/" document-id)
{:headers {"Authorization" (str "Bearer " token)
"Accept" "application/pdf"}
:as :byte-array})]
(:body response)))
(defn download-certificate
"Download Certificate of Completion (audit trail)"
[user-id envelope-id]
(let [token (auth/get-valid-token user-id)
token-info (db/get-token user-id)
account-id (:account-id token-info)
base-uri (:base-uri token-info)
response (http/get (str base-uri "/v2.1/accounts/" account-id
"/envelopes/" envelope-id
"/documents/certificate")
{:headers {"Authorization" (str "Bearer " token)
"Accept" "application/pdf"}
:as :byte-array})]
(:body response)))
Deliverables:
Code Example: Webhook Handler
(ns orcha.docusign.webhooks
(:require [ring.middleware.json :refer [wrap-json-body]]
[cheshire.core :as json]
[orcha.db.docusign :as db]
[orcha.docusign.envelopes :as envelopes]
[orcha.storage :as storage]
[orcha.workflows.approvals :as approvals]
[clojure.tools.logging :as log]))
(defn verify-docusign-signature
"Verify HMAC signature from DocuSign Connect"
[payload signature secret]
;; DocuSign signs webhook payloads with HMAC-SHA256
(let [calculated-sig (-> (javax.crypto.Mac/getInstance "HmacSHA256")
(doto (.init (javax.crypto.spec.SecretKeySpec.
(.getBytes secret) "HmacSHA256")))
(.doFinal (.getBytes payload))
(java.util.Base64/getEncoder)
(.encodeToString))]
(= calculated-sig signature)))
(defn handle-envelope-completed
"Handle envelope completion event"
[envelope-data]
(let [envelope-id (:envelopeId envelope-data)
envelope-record (db/get-envelope-by-envelope-id envelope-id)]
(when envelope-record
;; 1. Download signed document
(let [user-id (:user-id envelope-record)
signed-doc (envelopes/download-completed-document
user-id envelope-id "1")
certificate (envelopes/download-certificate user-id envelope-id)
;; 2. Store in S3 (GoBD-compliant)
signed-url (storage/upload-document
signed-doc
{:type :signed-document
:envelope-id envelope-id
:tenant-id (:tenant-id envelope-record)})
cert-url (storage/upload-document
certificate
{:type :certificate-of-completion
:envelope-id envelope-id
:tenant-id (:tenant-id envelope-record)})]
;; 3. Update envelope record
(db/update-envelope envelope-id
{:status "completed"
:completed-at (java.time.Instant/now)
:signed-document-url signed-url
:certificate-url cert-url})
;; 4. Trigger downstream workflows
(when (:approval-id envelope-record)
(approvals/mark-approved (:approval-id envelope-record)))
(when (:purchase-order-id envelope-record)
(activate-purchase-order (:purchase-order-id envelope-record)))
(log/info "Envelope completed and processed" {:envelope-id envelope-id})))))
(defn handle-envelope-declined
"Handle envelope declined event"
[envelope-data]
(let [envelope-id (:envelopeId envelope-data)
declined-by (:recipients envelope-data)
reason (:declinedReason envelope-data)]
(db/update-envelope envelope-id
{:status "declined"
:voided-at (java.time.Instant/now)
:voided-reason (str "Declined by: " reason)})
;; Notify stakeholders
(send-notification {:type :envelope-declined
:envelope-id envelope-id
:reason reason})
(log/warn "Envelope declined" {:envelope-id envelope-id :reason reason})))
(defn docusign-webhook-handler
"Main webhook handler endpoint"
[request]
(let [payload (slurp (:body request))
signature (get-in request [:headers "x-docusign-signature-1"])
secret (:docusign-webhook-secret config)]
;; Verify signature
(if (verify-docusign-signature payload signature secret)
(let [event-data (json/parse-string payload true)
envelope-status (get-in event-data [:envelopeStatus :status])]
;; Log event
(db/insert-envelope-event
{:envelope-id (get-in event-data [:envelopeStatus :envelopeId])
:event-type envelope-status
:raw-payload event-data
:timestamp (java.time.Instant/now)})
;; Handle based on status
(case envelope-status
"completed" (handle-envelope-completed (:envelopeStatus event-data))
"declined" (handle-envelope-declined (:envelopeStatus event-data))
"voided" (handle-envelope-voided (:envelopeStatus event-data))
(log/debug "Unhandled envelope status" {:status envelope-status}))
{:status 200 :body "OK"})
;; Invalid signature
(do
(log/error "Invalid DocuSign webhook signature")
{:status 401 :body "Unauthorized"}))))
(def webhook-routes
["/api/webhooks/docusign"
{:post {:handler docusign-webhook-handler
:middleware [wrap-json-body]}}])
Deliverables:
Code Example: Template Service
(ns orcha.docusign.templates
(:require [orcha.docusign.auth :as auth]
[clj-http.client :as http]
[cheshire.core :as json]
[orcha.db.docusign :as db]))
(defn create-template
"Create reusable DocuSign template"
[{:keys [user-id name description roles documents]}]
(let [token (auth/get-valid-token user-id)
token-info (db/get-token user-id)
account-id (:account-id token-info)
base-uri (:base-uri token-info)
template-def {:name name
:description description
:emailSubject (str "Please sign: " name)
:shared "false"
:documents documents
:recipients {:signers roles}}
response (http/post (str base-uri "/v2.1/accounts/" account-id "/templates")
{:headers {"Authorization" (str "Bearer " token)
"Content-Type" "application/json"}
:body (json/generate-string template-def)
:as :json})]
(:body response)))
(defn list-templates
"List all templates for account"
[user-id]
(let [token (auth/get-valid-token user-id)
token-info (db/get-token user-id)
account-id (:account-id token-info)
base-uri (:base-uri token-info)
response (http/get (str base-uri "/v2.1/accounts/" account-id "/templates")
{:headers {"Authorization" (str "Bearer " token)}
:as :json})]
(get-in response [:body :envelopeTemplates])))
;; Example: Purchase Order Template
(def purchase-order-template
{:name "Purchase Order Approval"
:description "Standard PO approval workflow with vendor acknowledgment"
:roles [{:roleName "Department Head"
:routingOrder "1"
:tabs {:signHereTabs [{:anchorString "/dept_sig/"
:anchorXOffset "0"
:anchorYOffset "0"}]
:dateSignedTabs [{:anchorString "/dept_date/"
:anchorXOffset "0"
:anchorYOffset "0"}]
:textTabs [{:tabLabel "PO_Number"
:value ""
:anchorString "/po_number/"
:anchorXOffset "0"
:anchorYOffset "0"}
{:tabLabel "Amount"
:value ""
:anchorString "/amount/"
:anchorXOffset "0"
:anchorYOffset "0"}]}}
{:roleName "CFO"
:routingOrder "2"
:tabs {:signHereTabs [{:anchorString "/cfo_sig/"
:anchorXOffset "0"
:anchorYOffset "0"}]
:dateSignedTabs [{:anchorString "/cfo_date/"
:anchorXOffset "0"
:anchorYOffset "0"}]}}
{:roleName "Vendor"
:routingOrder "3"
:tabs {:signHereTabs [{:anchorString "/vendor_sig/"
:anchorXOffset "0"
:anchorYOffset "0"}]
:dateSignedTabs [{:anchorString "/vendor_date/"
:anchorXOffset "0"
:anchorYOffset "0"}]
:textTabs [{:tabLabel "Vendor_Name"
:value ""
:anchorString "/vendor_name/"
:anchorXOffset "0"
:anchorYOffset "0"}]}}]})
Deliverables:
Code Example: Conditional Routing
(defn create-approval-envelope
"Create envelope with conditional routing based on amount"
[{:keys [invoice approval-amount department-head cfo vendor]}]
(let [requires-cfo? (> approval-amount 10000)
recipients (cond-> []
;; Always include department head
true (conj {:roleName "Department Head"
:name (:name department-head)
:email (:email department-head)
:routingOrder "1"})
;; Add CFO if amount > €10K
requires-cfo? (conj {:roleName "CFO"
:name (:name cfo)
:email (:email cfo)
:routingOrder "2"})
;; Vendor always last
true (conj {:roleName "Vendor"
:name (:name vendor)
:email (:email vendor)
:routingOrder (if requires-cfo? "3" "2")}))]
(envelopes/create-envelope
{:user-id (:user-id invoice)
:template-id (get-template-id :purchase-order)
:recipients recipients
:subject (str "Purchase Order Approval - " (:invoice-number invoice))})))
Before DocuSign:
After DocuSign:
Time Saved:
Total: 990 days/year = €100,000-150,000 in productivity gains
Audit Defense:
Value: €20,000-50,000/year in audit cost savings
Compliance Confidence:
Value: Risk mitigation (unquantified, but critical)
Early Payment Discounts (Phase 3.2):
Value: Enables €200,000/year in early payment discounts
Contract Compliance (Phase 2.1):
Value: Reduces disputes, improves vendor scorecards
Scale Approvals:
Value: €50,000-100,000/year in avoided headcount costs (at scale)
Annual Value:
Implementation Cost:
ROI: 5-8x in Year 1, 10-15x in Year 2+
DocuSign provides three levels of electronic signatures under eIDAS:
Simple Electronic Signature (SES)
Advanced Electronic Signature (AES)
Qualified Electronic Signature (QES)
Orcha Recommendation:
German law recognizes electronic signatures as equivalent to handwritten signatures if:
DocuSign Compliance: ✅ Yes, DocuSign AES meets all requirements.
DocuSign integrates with GoBD requirements:
Orcha Implementation:
1. Market Leader
2. Legal Recognized
3. API Maturity
4. Integration Ecosystem
5. User Experience
SignNow (barracuda):
Adobe Sign:
Build In-House:
Decision: DocuSign is the best balance of features, cost, legal compliance, and market acceptance for German SMEs.
Month 1: Core Integration
Month 2: Approval Workflows
Month 3: Templates & Contracts
Month 4: Advanced Features
Phase 1 (Months 1-2):
Phase 2 (Months 3-4):
Long-Term (12 months):
┌────────────────────────────────────────────────────────────────┐
│ 🤖 APPROVAL REQUEST: Purchase Order PO-2024-1234 │
│ Vendor: Acme Office Supplies | Amount: €8,450 │
├────────────────────────────────────────────────────────────────┤
│ │
│ ✅ 4-WAY MATCH VALIDATION │
│ ✓ Invoice matches PO (variance: -0.6%) │
│ ✓ Goods received and confirmed │
│ ✓ Contract terms compliant │
│ │
│ 🤖 AI RECOMMENDATION: AUTO-APPROVE (98% confidence) │
│ │
│ ⚠️ SIGNATURE REQUIRED (Amount > €5,000) │
│ │
│ This purchase order requires your electronic signature │
│ to create a legally binding agreement with the vendor. │
│ │
│ By signing, you: │
│ • Authorize the purchase of goods/services as specified │
│ • Commit to payment terms (net 30 days) │
│ • Create enforceable contract with vendor │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ [✍️ SIGN WITH DOCUSIGN] │ │
│ │ │ │
│ │ Signing process: │ │
│ │ 1. You sign electronically │ │
│ │ 2. CFO signs (if applicable) │ │
│ │ 3. Vendor acknowledges terms │ │
│ │ 4. Signed PO returned to Orcha │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ [❌ REJECT] [⏸️ HOLD] [📄 VIEW DETAILS] │
│ │
└────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐
│ DOCUSIGN ENVELOPES - ACTIVE │
├────────────────────────────────────────────────────────────────┤
│ │
│ PO-2024-1234 | Acme Office Supplies | €8,450 │
│ Status: Waiting for signatures (2 of 3 completed) │
│ │
│ ✅ Maria Weber (Dept Head) - Signed Jan 5, 11:15 AM │
│ ✅ Klaus Müller (CFO) - Signed Jan 5, 11:42 AM │
│ ⏳ Johann Schmidt (Vendor) - Sent Jan 5, 11:45 AM │
│ Last viewed: Jan 5, 2:30 PM │
│ │
│ [📧 Send Reminder] [❌ Cancel] [📄 View Document] │
│ │
│ ───────────────────────────────────────────────────────────── │
│ │
│ MSA-2024-0045 | IT Services GmbH | Annual Contract │
│ Status: Completed ✅ (Jan 3, 4:15 PM) │
│ │
│ ✅ Klaus Müller (CFO) - Signed Jan 3, 10:22 AM │
│ ✅ Hans Becker (Vendor Legal) - Signed Jan 3, 2:15 PM │
│ ✅ Anna Schmidt (Vendor CFO) - Signed Jan 3, 4:12 PM │
│ │
│ [📥 Download] [🔍 View Certificate] [📊 Extract Terms] │
│ │
└────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐
│ DOCUSIGN TEMPLATES │
├────────────────────────────────────────────────────────────────┤
│ │
│ Purchase Order Approval │
│ Roles: Department Head → CFO (conditional) → Vendor │
│ Used: 147 times | Avg completion: 18 hours │
│ [📝 Edit] [📋 Use Template] [📊 Analytics] │
│ │
│ ───────────────────────────────────────────────────────────── │
│ │
│ Master Service Agreement │
│ Roles: CFO → Vendor Legal → Vendor CFO │
│ Used: 23 times | Avg completion: 2.3 days │
│ [📝 Edit] [📋 Use Template] [📊 Analytics] │
│ │
│ ───────────────────────────────────────────────────────────── │
│ │
│ High-Value Invoice Approval (>€50K) │
│ Roles: Controller → CFO │
│ Used: 89 times | Avg completion: 4 hours │
│ [📝 Edit] [📋 Use Template] [📊 Analytics] │
│ │
│ ───────────────────────────────────────────────────────────── │
│ │
│ [➕ CREATE NEW TEMPLATE] │
│ │
└────────────────────────────────────────────────────────────────┘
1. DocuSign API Downtime
2. Webhook Delivery Failure
3. Token Expiration
1. User Adoption
2. External Party Resistance
3. Legal Challenges
1. GoBD Non-Compliance
2. Data Privacy (GDPR)
DocuSign is NOT fully white-labeled, but offers significant branding customization:
✅ Email Branding
noreply@orcha.com with DKIM setup)✅ Signing Page Branding
✅ Email Templates
❌ "Powered by DocuSign" Branding
❌ DocuSign URLs
docusign.net domain❌ DocuSign Mobile App
Email:
From: Orcha Approvals <noreply@orcha.com>
Subject: Please sign: Purchase Order PO-2024-1234
[ORCHA LOGO]
Hi Johann,
Maria Weber from Acme GmbH has requested your signature
on a purchase order (€8,450.00).
[REVIEW AND SIGN BUTTON]
This document is managed by Orcha and secured by DocuSign.
---
Powered by DocuSign | View in DocuSign App
Assessment: The branding is professional and acceptable. Most recipients recognize DocuSign as a trusted platform, which actually increases trust rather than detracting from Orcha's brand.
For Internal Users (Orcha Customers):
Users never leave the Orcha platform:
┌────────────────────────────────────────────────────────┐
│ ORCHA PLATFORM (orcha.com) │
│ ┌──────────────────────────────────────────────────┐ │
│ │ APPROVAL REQUEST PO-2024-1234 │ │
│ │ Amount: €8,450 │ │
│ │ │ │
│ │ ✅ 4-Way Match Complete │ │
│ │ 🤖 AI Recommends: APPROVE │ │
│ │ │ │
│ │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │ │
│ │ │ │
│ │ [Embedded DocuSign Signing Iframe Below] │ │
│ │ ┌──────────────────────────────────────────────┐│ │
│ │ │ Please sign to approve this purchase order ││ │
│ │ │ ││ │
│ │ │ ┌──────────────────────────────────────┐ ││ │
│ │ │ │ [Your Signature Here] │ ││ │
│ │ │ └──────────────────────────────────────┘ ││ │
│ │ │ ││ │
│ │ │ Date: January 5, 2026 ││ │
│ │ │ ││ │
│ │ │ [✅ SIGN AND APPROVE] ││ │
│ │ │ ││ │
│ │ │ Small "Powered by DocuSign" footer ││ │
│ │ └──────────────────────────────────────────────┘│ │
│ └──────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────┘
Implementation:
(defn get-embedded-signing-url
"Generate embedded signing URL for display in Orcha iframe"
[envelope-id recipient-id user-email user-name]
(let [token (auth/get-valid-token)
response (http/post
(str base-uri "/envelopes/" envelope-id
"/views/recipient")
{:headers {"Authorization" (str "Bearer " token)
"Content-Type" "application/json"}
:body (json/generate-string
{:returnUrl "https://orcha.com/approvals/complete"
:authenticationMethod "email"
:email user-email
:userName user-name
:clientUserId recipient-id})
:as :json})]
(-> response :body :url)))
;; Frontend: Display in iframe
;; <iframe src={embeddedSigningUrl}
;; width="100%"
;; height="600px"
;; frameborder="0" />
User Experience:
docusign.net URL visibleFor External Users (Vendors, Steuerberater):
They must use DocuSign's signing pages:
docusign.net signing pageUser Experience:
Why This is Actually Good:
How It Works:
DocuSign Pricing:
Base Account:
├─ DocuSign Business Pro: $40-50/user/month
├─ Minimum: 3 users required = $120-150/month base
└─ API access included
Envelope Fees:
├─ Standard envelopes: $0.50 per envelope
├─ Advanced envelopes: $1.00 per envelope (complex routing)
└─ Volume discounts kick in at 5,000+/month
Example Calculation (50 Orcha customers):
├─ Base: $150/month
├─ Average: 200 envelopes/customer/month = 10,000 envelopes
├─ Cost: $150 + (10,000 × $0.50) = $5,150/month
└─ Per customer: $103/month average
Volume Pricing (Negotiable at Scale):
Tier 1: 0-5,000 envelopes/month
→ $0.50 per envelope
Tier 2: 5,000-20,000 envelopes/month
→ $0.35 per envelope (30% discount)
Tier 3: 20,000-50,000 envelopes/month
→ $0.25 per envelope (50% discount)
Enterprise: 50,000+ envelopes/month
→ Flat fee negotiation (e.g., $10K/month unlimited)
→ Effective: $0.10-0.20 per envelope
Orcha's Pricing to Customers:
Option 1: Add-On Pricing
├─ Base Orcha subscription: €299/month
├─ DocuSign Electronic Signatures: +€89/month
│ ├─ Includes: 200 envelopes/month
│ └─ Additional: €0.50 per envelope
└─ Total: €388/month
Option 2: Bundled Pricing
├─ Orcha Premium: €349/month
│ ├─ AP Automation
│ ├─ Procurement Intelligence
│ ├─ DocuSign Signatures (200 envelopes)
│ └─ All features included
└─ Simplifies sales (one price)
Profitability Analysis:
At Launch (50 customers, no volume discount):
Revenue: 50 customers × €89/month = €4,450/month
Cost: $150 base + (10,000 × $0.50) = $5,150/month (€4,850)
Margin: -€400/month (8% loss initially)
At Scale (100 customers, Tier 2 volume discount):
Revenue: 100 customers × €89/month = €8,900/month
Cost: $150 base + (20,000 × $0.35) = $7,150/month (€6,700)
Margin: +€2,200/month (25% profit)
At Enterprise Scale (200+ customers, flat fee deal):
Revenue: 200 customers × €89/month = €17,800/month
Cost: $10,000/month flat (€9,400)
Margin: +€8,400/month (47% profit)
Recommendation: Accept initial loss leader to gain market share, negotiate volume discount at 100+ customers.
How It Works:
Pricing:
Per Customer:
├─ DocuSign Business Pro: $40-65/user/month
├─ Typical: 2-5 users (CFO, Controller, Approvers)
├─ Total: $80-325/month paid to DocuSign
└─ Orcha integration fee: €25/month
Why NOT Recommended:
❌ Complex Onboarding
❌ Support Nightmare
❌ Higher Perceived Cost
❌ Competitive Disadvantage
✅ Only Advantage: Orcha has zero DocuSign costs
Decision: Model A (Orcha as master account) is strongly recommended despite initial loss leader.
Answer: NO - Orcha creates "virtual users" for them
How It Works:
┌─────────────────────────────────────────────────────────┐
│ ORCHA'S DOCUSIGN MASTER ACCOUNT │
├─────────────────────────────────────────────────────────┤
│ │
│ Virtual User 1: maria@customer-a.de (CFO) │
│ Virtual User 2: klaus@customer-a.de (Controller) │
│ Virtual User 3: anna@customer-b.de (CFO) │
│ Virtual User 4: thomas@customer-b.de (Controller) │
│ ... │
│ Virtual User N: [Unlimited users] │
│ │
└─────────────────────────────────────────────────────────┘
Implementation Steps:
1. Orcha signs up for DocuSign Business Pro
2. Orcha creates integration (gets Integration Key + Secret)
3. Orcha enables JWT Grant in DocuSign admin
4. Orcha generates RSA key pair for JWT signing
(defn create-virtual-docusign-user
"Create virtual DocuSign user for Orcha customer (no real account)"
[orcha-user-id email name]
(let [;; Generate JWT token for Orcha's account
jwt-token (generate-jwt-token
{:integration-key orcha-integration-key
:user-id orcha-docusign-account-id
:scopes ["signature" "impersonation"]
:expires-in 3600})
;; Get access token
access-token (exchange-jwt-for-token jwt-token)
;; Create impersonation consent (one-time per user)
consent (grant-impersonation-consent
access-token
{:email email
:name name
:client-user-id (str "orcha-" orcha-user-id)})]
;; Store mapping in Orcha database
(db/insert :docusign-virtual-users
{:orcha-user-id orcha-user-id
:docusign-user-id (:user-id consent)
:email email
:name name
:client-user-id (str "orcha-" orcha-user-id)
:consent-granted-at (now)})))
(defn send-envelope-as-user
"Send DocuSign envelope impersonating Orcha user"
[orcha-user-id envelope-data]
(let [virtual-user (db/get-virtual-user orcha-user-id)
;; Generate JWT for this specific user
jwt-token (generate-jwt-token
{:integration-key orcha-integration-key
:user-id (:docusign-user-id virtual-user)
:account-id orcha-docusign-account-id
:scopes ["signature" "impersonation"]
:expires-in 3600})
access-token (exchange-jwt-for-token jwt-token)]
;; Create envelope (appears to come from virtual-user)
(docusign/create-envelope access-token envelope-data)))
User Experience:
First Time Only (One-Time Consent):
┌────────────────────────────────────────────────────────┐
│ DOCUSIGN CONSENT REQUEST │
├────────────────────────────────────────────────────────┤
│ │
│ Orcha would like to send documents for signature │
│ on your behalf using DocuSign. │
│ │
│ By approving, you allow: │
│ • Orcha to send envelopes from your email │
│ • Recipients to see your name as sender │
│ • DocuSign to process documents securely │
│ │
│ [APPROVE] [LEARN MORE] │
│ │
└────────────────────────────────────────────────────────┘
After Approval:
Cost Impact:
Month 1-2:
Customer Experience:
docusign.net URLsCost:
Month 3-4:
Vendor Experience:
docusign.net page with Orcha logoCost: Same per-envelope fee ($0.50)
Month 6+ (at 10,000+ envelopes/month):
Profitability:
| Factor | DocuSign Direct | Orcha + DocuSign |
|---|---|---|
| Setup | Customer must buy DocuSign | Included in Orcha |
| Monthly Cost | $80-325/customer | €89/customer |
| User Seats | $40-65 per user | Unlimited users |
| Envelopes | 100-500 included, then $1 each | 200 included, then €0.50 |
| Integration | Manual (no API) | Seamless (embedded) |
| Support | Two vendors (Orcha + DocuSign) | One vendor (Orcha) |
| Onboarding | 2-4 weeks | Instant |
| Signing Experience | Always external | Embedded for internal |
Customer Savings: €111-236/month (40-75% cheaper through Orcha)
Why Customers Choose Orcha:
Don't Say:
Do Say:
Positioning:
"Orcha includes legally binding electronic signatures (powered by DocuSign) at no extra cost. Sign purchase orders, contracts, and approvals directly in Orcha—no separate accounts, no complexity, just secure signatures that are legally recognized across the EU."
Pricing:
Competitive Advantage:
Strategic Fit:
Customer Value:
Market Positioning:
Proceed with Integration (Priority: High)
Rationale:
Timeline: 4 months to full production
Investment: €30-50K development + €40-60/user/year
Expected Outcome: 95%+ electronic signature adoption, €320-400K annual value per customer
GET /oauth/auth - Authorization URLPOST /oauth/token - Exchange code for tokenPOST /oauth/token - Refresh access tokenGET /oauth/userinfo - Get user account infoPOST /v2.1/accounts/{accountId}/envelopes - Create envelopeGET /v2.1/accounts/{accountId}/envelopes/{envelopeId} - Get statusPUT /v2.1/accounts/{accountId}/envelopes/{envelopeId} - Update/voidGET /v2.1/accounts/{accountId}/envelopes/{envelopeId}/documents/{documentId} - Download documentGET /v2.1/accounts/{accountId}/envelopes/{envelopeId}/documents/certificate - Download certificatePOST /v2.1/accounts/{accountId}/templates - Create templateGET /v2.1/accounts/{accountId}/templates - List templatesGET /v2.1/accounts/{accountId}/templates/{templateId} - Get templatePUT /v2.1/accounts/{accountId}/templates/{templateId} - Update templatePOST /v2.1/accounts/{accountId}/envelopes/{envelopeId}/recipients - Add recipientsPUT /v2.1/accounts/{accountId}/envelopes/{envelopeId}/recipients/{recipientId} - Update recipientPOST /v2.1/accounts/{accountId}/envelopes/{envelopeId}/recipients/{recipientId}/views/recipient - Get signing URLenvelope-sent, envelope-delivered, envelope-completed, envelope-declined, envelope-voided, recipient-completedOfficial Documentation:
Legal & Compliance:
SDKs:
Orcha Internal:
Document Version: 1.0
Last Updated: January 5, 2026
Author: Orcha Product Team
Status: Approved for Development