Documenso Sdk PatternsSAFE
Model-agnostic agent-skills platform with a harness-free canonical layer, verified adapters, and the ccpi package manager. Explore at tonsofskills.com.
Overview
Model-agnostic agent-skills platform with a harness-free canonical layer, verified adapters, and the ccpi package manager. Explore at tonsofskills.com.
4f83675ca38aOBSERVED · 2026-10-08Host compatibility
What the documentation claims. We have not run a compatibility test.
| Host | Status | Notes |
|---|---|---|
| claude-code | mentioned |
What it tells the agent
The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.
--- name: documenso-sdk-patterns description: 'Apply production-ready Documenso SDK patterns for TypeScript and Python. Use when implementing Documenso integrations, refactoring SDK usage, or establishing team coding standards for Documenso. Trigger with phrases like "documenso SDK patterns", "documenso best practices", "documenso code patterns", "idiomatic documenso". ' allowed-tools: Read, Write, Edit version: 1.14.0 license: MIT author: Jeremy Longshore <[email protected]> tags: - saas - documenso - python - typescript compatibility: Designed for Claude Code --- # Documenso SDK Patterns ## Output - A scoped SDK boundary with document authorization, idempotency, redacted telemetry, and safe error handling. - A test-backed client design that never logs signing URLs, document content, signer PII, or credentials. ## Examples Instantiate the SDK with a development secret reference, create a synthetic test document with a stable idempotency key, and assert the mocked request shape in unit tests. For one development integration check, record only correlation ID and lifecycle state; never log document or signer payloads. ## Overview Production-ready patterns for the Documenso TypeScript SDK (`@documenso/sdk-typescript`) and Python SDK. Covers singleton clients, typed wrappers, error handling, retry logic, and testing patterns. ## Prerequisites - Completed `documenso-install-auth` setup - Familiarity with async/await and TypeScript generics - Understanding of error handling best practices ## Instructions ### Pattern 1: Singleton Client with Configuration ```typescript // src/documenso/client.ts import { Documenso } from "@documenso/sdk-typescript"; interface DocumensoConfig { apiKey: string; baseUrl?: string; timeout?: number; } let instance: Documenso | null = null; export function getDocumensoClient(config?: DocumensoConfig): Documenso { if (!instance) { const apiKey = config?.apiKey ?? process.env.DOCUMENSO_API_KEY; if (!apiKey) throw new Error("DOCUMENSO_API_KEY is required"); instance = new Documenso({ apiKey, ...(config?.baseUrl && { serverURL: config.baseUrl }), }); } return instance; } // Reset for testing export function resetClient(): void { instance = null; } ``` ### Pattern 2: Typed Document Service ```typescript // src/documenso/documents.ts import { getDocumensoClient } from "./client"; export interface CreateDocumentInput { title: string; pdfPath: string; signers: Array<{ email: string; name: string; fields: Array<{ type: "SIGNATURE" | "INITIALS" | "NAME" | "EMAIL" | "DATE" | "TEXT"; pageNumber: number; pageX: number; pageY: number; pageWidth?: number; pageHeight?: number; }>; }>; } export interface DocumentResult { documentId: number; recipientIds: number[]; status: "DRAFT" | "PENDING" | "COMPLETED"; } export async function createAndSendDocument( input: CreateDocumentInput ): Promise<DocumentResult> { const client = getDocumensoClient(); const { readFileSync } = await import("fs"); // Create document const doc = await client.documents.createV0({ title: input.title }); // Upload PDF const pdfBuffer = readFileSync(input.pdfPath); await client.documents.setFileV0(doc.documentId, { file: new Blob([pdfBuffer], { type: "application/pdf" }), }); // Add recipients and fields const recipientIds: number[] = []; for (const signer of input.signers) { const recipient = await client.documentsRecipients.createV0(doc.documentId, { email: signer.email, name: signer.name, role: "SIGNER", }); recipientIds.push(recipient.recipientId); for (const field of signer.fields) { await client.documentsFields.createV0(doc.documentId, { recipientId: recipient.recipientId, type: field.type, pageNumber: field.pageNumber, pageX: field.pageX, pageY: field.pageY, pageWidth: field.pageWidth ?? 20, pageHeight: field.pageHeight ?? 5, }); } } // Send await client.documents.sendV0(doc.documentId); return { documentId: doc.documentId, recipientIds, status: "PENDING" }; } ``` ### Pattern 3: Error Handling Wrapper ```typescript // src/documenso/errors.ts export class DocumensoError extends Error { constructor( message: string, public statusCode?: number, public retryable: boolean = false ) { super(message); this.name = "DocumensoError"; } } export async function withErrorHandling<T>( operation: string, fn: () => Promise<T> ): Promise<T> { try { return await fn(); } catch (err: any) { const status = err.statusCode ?? err.status; switch (status) { case 401: throw new DocumensoError(`${operation}: Invalid API key`, 401, false); case 403: throw new DocumensoError( `${operation}: Insufficient permissions — use team API key`, 403, false ); case 404: throw new DocumensoError(`${operation}: Resource not found`, 404, false); case 429: throw new DocumensoError(`${operation}: Rate limited`, 429, true); case 500: case 502: case 503: throw new DocumensoError( `${operation}: Documenso server error`, status, true ); default: throw new DocumensoError( `${operation}: ${err.message ?? "Unknown error"}`, status, false ); } } } ``` ### Pattern 4: Retry with Exponential Backoff ```typescript // src/documenso/retry.ts import { DocumensoError } from "./errors"; interface RetryConfig { maxRetries: number; baseDelayMs: number; maxDelayMs: number; } const DEFAULT_RETRY: RetryConfig = { maxRetries: 3, baseDelayMs: 1000, maxDelayMs: 30000, }; export async function withRetry<T>( fn: () => Promise<T>, config: Partial<RetryConfig> = {} ): Promise<T> { const { maxRetries, ba
Trust audit
SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | PASS |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- none-observed
- Network
- none-observed
- Shell
- none-observed
- Dependencies
- pinned
- Secrets in source
- none-found
Findings (0)
No findings outside the package's declared scope.
Gates applied: no_behavioural_pass.
4f83675ca38afull audit observations/trust-audit/skill/jeremylongshore__documenso-sdk-patterns.json · Report an issue / request a re-scanAudit history
Every audit this skill has had.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-08 | 4f83675ca38a | SAFE | B | 89 | first audit |
Questions
What does the Documenso Sdk Patterns skill do?
Model-agnostic agent-skills platform with a harness-free canonical layer, verified adapters, and the ccpi package manager. Explore at tonsofskills.com.
Is Documenso Sdk Patterns safe to install?
The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean skill reads B.
What can Documenso Sdk Patterns access on my machine?
The audit observed no filesystem, network or shell use at all in its source.
Which assistants does Documenso Sdk Patterns work with?
Its documentation mentions claude-code. That is what the text claims, not a compatibility test we ran.
How current is this page?
The grade is for one exact copy of the source (4f83675ca38a), read on 2026-10-08. The repository is watched, and a new audit runs when it changes — this is the first audit.