Documenso Rate LimitsSAFE
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-rate-limits description: 'Implement Documenso rate limiting, backoff, and request throttling patterns. Use when handling rate limit errors, implementing retry logic, or optimizing API request throughput for Documenso. Trigger with phrases like "documenso rate limit", "documenso throttling", "documenso 429", "documenso retry", "documenso backoff". ' allowed-tools: Read, Write, Edit version: 1.14.0 license: MIT author: Jeremy Longshore <[email protected]> tags: - saas - documenso - api compatibility: Designed for Claude Code --- # Documenso Rate Limits ## Output - A rate-aware document/signing integration with bounded concurrency, idempotency, backoff, monitoring, and replay ownership. - A safe throttle/recovery receipt that avoids duplicate invitations, duplicate signatures, or accidental document changes. ## Examples Exercise a development API with synthetic documents at controlled concurrency, retain stable idempotency keys, and record aggregate 429/latency/completion results. Back off with jitter on throttling; do not retry document creation or signature actions without verifying their current state. ## Overview Documenso uses a fair-use rate limiting model. There are no published per-minute request quotas -- instead, limits are based on your plan's document allowance and general API fair use. The paid plans (Individual and Team) include unlimited signing and API volume. The free plan has a document limit. If you hit a 429, implement exponential backoff and request queuing. ## Prerequisites - Documenso SDK installed - Understanding of async/await patterns - Completed `documenso-install-auth` setup ## Documenso Fair Use Model | Plan | Documents | API Volume | Signing Volume | |------|-----------|------------|----------------| | Free | Limited (per plan) | Fair use | Fair use | | Individual ($30/mo) | Unlimited | Unlimited | Unlimited | | Team | Unlimited | Unlimited | Unlimited | | Enterprise | Unlimited | Unlimited | Unlimited | | Self-Hosted | Unlimited | No limits | No limits | Documenso explicitly does not price API usage -- they want developers to build on the platform without API cost concerns. The practical limit is abusive traffic patterns (thousands of requests per second). ## Instructions ### Step 1: Exponential Backoff with Jitter ```typescript // src/documenso/retry.ts interface RetryConfig { maxRetries: number; baseDelayMs: number; maxDelayMs: number; } const DEFAULTS: RetryConfig = { maxRetries: 5, baseDelayMs: 1000, maxDelayMs: 60000 }; export async function withRetry<T>( fn: () => Promise<T>, config: Partial<RetryConfig> = {} ): Promise<T> { const { maxRetries, baseDelayMs, maxDelayMs } = { ...DEFAULTS, ...config }; let lastError: Error | undefined; for (let attempt = 0; attempt <= maxRetries; attempt++) { try { return await fn(); } catch (err: any) { lastError = err; const status = err.statusCode ?? err.status; // Don't retry client errors (except 429) if (status && status >= 400 && status < 500 && status !== 429) { throw err; } if (attempt === maxRetries) break; // Exponential backoff with jitter const delay = Math.min(baseDelayMs * 2 ** attempt, maxDelayMs); const jitter = delay * (0.5 + Math.random() * 0.5); console.warn(`Retry ${attempt + 1}/${maxRetries} in ${Math.round(jitter)}ms (status: ${status})`); await new Promise((r) => setTimeout(r, jitter)); } } throw lastError!; } ``` ### Step 2: Request Queue for Bulk Operations ```typescript // src/documenso/queue.ts import PQueue from "p-queue"; // Limit concurrency to avoid overwhelming the API const queue = new PQueue({ concurrency: 5, interval: 1000, intervalCap: 10 }); export async function queuedRequest<T>(fn: () => Promise<T>): Promise<T> { return queue.add(fn) as Promise<T>; } // Usage: bulk document creation async function createBulkDocuments( client: Documenso, items: Array<{ title: string; pdfPath: string }> ) { const results = await Promise.allSettled( items.map((item) => queuedRequest(async () => { const doc = await client.documents.createV0({ title: item.title }); const pdf = readFileSync(item.pdfPath); await client.documents.setFileV0(doc.documentId, { file: new Blob([pdf], { type: "application/pdf" }), }); return doc; }) ) ); const succeeded = results.filter((r) => r.status === "fulfilled").length; const failed = results.filter((r) => r.status === "rejected").length; console.log(`Bulk create: ${succeeded} succeeded, ${failed} failed`); return results; } ``` ### Step 3: Circuit Breaker for Outages ```typescript // src/documenso/circuit-breaker.ts class CircuitBreaker { private failures = 0; private lastFailure = 0; private state: "closed" | "open" | "half-open" = "closed"; constructor( private threshold = 5, // failures before opening private resetTimeMs = 30000 // time before half-open ) {} async execute<T>(fn: () => Promise<T>): Promise<T> { if (this.state === "open") { if (Date.now() - this.lastFailure > this.resetTimeMs) { this.state = "half-open"; } else { throw new Error("Circuit breaker is open — Documenso API unavailable"); } } try { const result = await fn(); this.onSuccess(); return result; } catch (err) { this.onFailure(); throw err; } } private onSuccess() { this.failures = 0; this.state = "closed"; } private onFailure() { this.failures++; this.lastFailure = Date.now(); if (this.failures >= this.threshold) { this.state = "open"; console.error(`Circuit breaker OPEN after ${this.failures} failures`); } } } // Usage const breaker = new CircuitBreaker(); const doc = await breaker.execute(() => client.documents.findV0({ page: 1, perPage: 10 })); ``` ### Step 4: Pytho
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-rate-limits.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 Rate Limits 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 Rate Limits 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 Rate Limits access on my machine?
The audit observed no filesystem, network or shell use at all in its source.
Which assistants does Documenso Rate Limits 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.