---
name: documenso-upgrade-migration-9041e7d18a55
description: |
  Execute Documenso API version upgrades and SDK migrations.
  Use when upgrading from v1 to v2 API, updating SDK versions,
  or migrating between Documenso versions.
  Trigger with phrases like "documenso upgrade", "documenso v2 migration",
  "update documenso SDK", "documenso API version".
allowed-tools: Read, Write, Edit, Bash(npm:*)
version: 1.0.0
license: MIT
author: Jeremy Longshore <jeremy@intentsolutions.io>
---

# Documenso Upgrade & Migration

## Overview
Guide for upgrading Documenso SDK versions and migrating from API v1 to v2.

## Prerequisites
- Current Documenso integration working
- Test environment available
- Feature flag system (recommended)
- Backup/rollback plan

## API Version Differences

### v1 vs v2 Comparison

| Feature | API v1 | API v2 |
|---------|--------|--------|
| Status | Deprecated | Current |
| SDK Support | Limited | Full TypeScript/Python/Go |
| Documents | `/api/v1/documents` | `/api/v2/documents` |
| Templates | `/api/v1/templates` | `/api/v2/templates` |
| Envelopes | N/A | `/api/v2/envelopes` (new) |
| ID Format | Numeric | Prefixed (doc_, tmpl_, etc.) |
| Batch Operations | No | Yes |
| File Streaming | No | Yes |

## Migration Steps

### Step 1: Update SDK

```bash
# Remove old SDK (if any custom v1 implementation)
npm uninstall your-documenso-v1-wrapper

# Install v2 SDK
npm install @documenso/sdk-typescript

# For Python
pip install --upgrade documenso_sdk
```

### Step 2: Update Import Statements

```typescript
// Before (v1 - hypothetical)
import { DocumensoClient } from "documenso-v1";

// After (v2)
import { Documenso } from "@documenso/sdk-typescript";
```

### Step 3: Update Client Initialization

```typescript
// Before (v1)
const client = new DocumensoClient({
  apiKey: process.env.DOCUMENSO_API_KEY,
  baseUrl: "https://app.documenso.com/api/v1",
});

// After (v2)
const client = new Documenso({
  apiKey: process.env.DOCUMENSO_API_KEY ?? "",
  serverURL: "https://app.documenso.com/api/v2/",
});
```

### Step 4: Update Document Operations

```typescript
// Before (v1)
const document = await client.documents.create({
  title: "My Document",
  file: fileBuffer,
});
const docId = document.id;  // Numeric: 12345

// After (v2)
// Note: createV0 is used during beta, will become create
const document = await client.documents.createV0({
  title: "My Document",
  file: pdfBlob,
});
const docId = document.documentId;  // Prefixed: doc_abc123
```

### Step 5: Update Recipient Operations

```typescript
// Before (v1)
await client.documents.addRecipient(docId, {
  email: "signer@example.com",
  name: "John Doe",
  role: "signer",
});

// After (v2)
await client.documentsRecipients.createV0({
  documentId: docId,
  email: "signer@example.com",
  name: "John Doe",
  role: "SIGNER",  // Note: uppercase enum
});
```

### Step 6: Update Field Operations

```typescript
// Before (v1)
await client.documents.addField(docId, recipientId, {
  type: "signature",
  page: 1,
  x: 100,
  y: 600,
  width: 200,
  height: 60,
});

// After (v2)
await client.documentsFields.createV0({
  documentId: docId,
  recipientId: recipientId,
  type: "SIGNATURE",  // Note: uppercase enum
  page: 1,
  positionX: 100,     // Note: renamed from x/y
  positionY: 600,
  width: 200,
  height: 60,
});
```

### Step 7: Update Template Usage

```typescript
// Before (v1)
const doc = await client.templates.createDocument(templateId, {
  recipients: [{ email: "signer@example.com", name: "John" }],
});

// After (v2)
const envelope = await client.envelopes.useV0({
  templateId: templateId,
  recipients: [
    {
      email: "signer@example.com",
      name: "John",
      signerIndex: 0,
    },
  ],
});
```

### Step 8: Update Webhook Handlers

```typescript
// Before (v1)
interface V1WebhookPayload {
  type: string;
  document: {
    id: number;
    title: string;
    status: string;
  };
}

// After (v2)
interface V2WebhookPayload {
  event: string;  // Note: renamed from type
  payload: {
    id: string;   // Note: string prefixed ID
    title: string;
    status: string;
    recipients: Array<{
      email: string;
      signingStatus: string;
    }>;
  };
  createdAt: string;
  webhookEndpoint: string;
}

// Update handler
app.post("/webhooks/documenso", (req, res) => {
  const { event, payload } = req.body as V2WebhookPayload;

  switch (event) {
    case "document.completed":  // v2 event name
      handleDocumentCompleted(payload);
      break;
    case "document.signed":
      handleDocumentSigned(payload);
      break;
  }

  res.json({ received: true });
});
```

## Gradual Migration Strategy

### Step 1: Feature Flag Setup

```typescript
import { getDocumenso } from "./documenso-v2";
import { getLegacyClient } from "./documenso-v1";

async function getClient() {
  const useV2 = await featureFlags.isEnabled("documenso_v2");

  if (useV2) {
    return { client: getDocumenso(), version: "v2" };
  } else {
    return { client: getLegacyClient(), version: "v1" };
  }
}
```

### Step 2: Adapter Pattern

```typescript
// Create unified interface
interface DocumentService {
  createDocument(title: string, file: Blob): Promise<{ id: string }>;
  addRecipient(docId: string, email: string, name: string): Promise<void>;
  sendDocument(docId: string): Promise<void>;
}

// v1 adapter
class V1DocumentService implements DocumentService {
  async createDocument(title: string, file: Blob) {
    const doc = await v1Client.documents.create({ title, file });
    return { id: String(doc.id) };  // Convert numeric to string
  }
  // ... other methods
}

// v2 adapter
class V2DocumentService implements DocumentService {
  async createDocument(title: string, file: Blob) {
    const doc = await v2Client.documents.createV0({ title, file });
    return { id: doc.documentId! };
  }
  // ... other methods
}

// Factory
function getDocumentService(): DocumentService {
  return featureFlags.isEnabled("documenso_v2")
    ? new V2DocumentService()
    : new V1DocumentService();
}
```

### Step 3: Migration Rollout

```
Week 1: Deploy v2 code with feature flag OFF
Week 2: Enable v2 for internal users (5%)
Week 3: Enable v2 for beta users (20%)
Week 4: Enable v2 for all users (100%)
Week 5: Remove v1 code
```

## ID Migration

If you store document IDs in your database:

```typescript
// Migration script
async function migrateDocumentIds() {
  // v2 IDs have prefix, v1 IDs are numeric
  const documents = await db.documents.findAll({
    where: { documensoId: { notLike: 'doc_%' } }
  });

  for (const doc of documents) {
    // Fetch document from v2 API to get new ID
    // Note: You may need Documenso support for ID mapping
    console.log(`Migrate: ${doc.documensoId} -> doc_xxx`);
  }
}
```

## Testing Migration

```typescript
// Run both versions and compare
async function testMigration(testData: TestDocument) {
  const v1Result = await v1Service.createDocument(testData);
  const v2Result = await v2Service.createDocument(testData);

  // Compare results
  assert(v2Result.status === v1Result.status);
  assert(v2Result.recipients.length === v1Result.recipients.length);

  console.log("Migration test passed");
}
```

## Rollback Plan

```bash
# If v2 fails, rollback feature flag
featureFlags.disable("documenso_v2")

# Or deploy previous version
kubectl rollout undo deployment/signing-service
```

## Output
- Updated SDK to latest version
- Migrated from v1 to v2 API
- Feature flags controlling rollout
- Rollback procedure ready

## Error Handling
| Issue | Cause | Solution |
|-------|-------|----------|
| ID mismatch | v1 vs v2 format | Use adapter to normalize |
| Missing field | API change | Update to new field names |
| 404 on template | ID format changed | Fetch new template ID |
| Enum errors | Case sensitivity | Use uppercase enums |

## Resources
- [Documenso API v2 Documentation](https://openapi.documenso.com/)
- [SDK Changelog](https://github.com/documenso/sdk-typescript/releases)
- [Migration Guide](https://docs.documenso.com/developers/public-api)

## Next Steps
For CI/CD integration, see `documenso-ci-integration`.


---
Source attribution: Dicklesworthstone
Original project: https://github.com/Dicklesworthstone/pi_agent_rust/blob/f28fc46ee0db8e710d95b8b55592cd38d60f2b26/tests/ext_conformance/artifacts/plugins-community/plugins/saas-packs/documenso-pack/skills/documenso-upgrade-migration/SKILL.md
License: MIT
License information: https://opensource.org/license/mit
Original upstream instructions; downloaded from Mega AI Hub.

## Upstream license notice

MIT License (with OpenAI/Anthropic Rider)

Copyright (c) 2026 Jeffrey Emanuel

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

ADDITIONAL RIDER / RESTRICTION (OpenAI / Anthropic):

This rider is part of the "conditions" of this License. In the event of any
conflict between this rider and any other portion of this License, this rider
controls.

"Restricted Parties" means OpenAI, L.L.C.; Anthropic, PBC; any of their
respective Affiliates; and any person or entity acting directly or indirectly
on behalf of, for the benefit of, or under the direction of any of the
foregoing (including any officer, director, employee, contractor, agent,
consultant, service provider, or representative).

Notwithstanding any other provision of this License, no rights are granted to
any Restricted Party. Any purported license, sublicense, assignment, transfer,
or other permission to any Restricted Party is null and void absent the
express prior written permission of Jeffrey Emanuel.

You may not provide, disclose, distribute, sublicense, sell, lease, lend,
host, make available, or otherwise permit access to the Software or any
derivative work of the Software (as defined in applicable copyright law)
(collectively, "Derivative Works") to or for any Restricted Party.

For purposes of this rider, "use" includes, without limitation: copying,
modifying, merging, publishing, distributing, sublicensing, selling,
transferring, making available, hosting, deploying, executing, benchmarking,
testing, analyzing, indexing, or incorporating the Software or any Derivative
Works into any dataset, training corpus, evaluation harness, or pipeline for
machine learning or other automated systems.

This rider applies to the Software and all Derivative Works. As a condition of
use, you agree that this rider is a precondition to exercising any rights
under this License, and you agree that any distribution of the Software or any
Derivative Works must include this rider provision unmodified.

Any breach of this rider automatically and immediately terminates the
permissions granted by this License. Upon termination, you must immediately
cease all use and distribution of the Software and any Derivative Works and
destroy all copies under your control.

You agree that a breach of this rider would cause irreparable harm and that
Jeffrey Emanuel may seek injunctive or other equitable relief to enforce this
rider, in addition to any other remedies available at law. To the maximum
extent permitted by applicable law, the prevailing party in any action to
enforce this rider shall be entitled to recover reasonable attorneys' fees and
costs.

For purposes of this rider, "Affiliate" means any entity that directly or
indirectly controls, is controlled by, or is under common control with the
specified party. "Control" means ownership of more than 50% of the voting
securities or other ownership interest, or the power to direct management or
policies by contract or otherwise.

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.



# Mega AI Hub resource metadata

Creator / publisher: Dicklesworthstone
Original project: https://github.com/Dicklesworthstone/pi_agent_rust/blob/f28fc46ee0db8e710d95b8b55592cd38d60f2b26/tests/ext_conformance/artifacts/plugins-community/plugins/saas-packs/documenso-pack/skills/documenso-upgrade-migration/SKILL.md
Attribution basis: Source repository record

Fields of work: Development & Engineering, Product Management
Roles: Backend Developer, Product Manager, Technical Product Manager
Specialties: API, Backend
Tools: Documenso
Country applicability: Country not specified
Classification basis: Source catalog labels
Instruction SHA-256: ba73cb12f690180fdfc7eb5a8d812338fe28fd27f90c89c73f64b367599df70b
