---
title: "SDKs Overview"
description: "Official TurboDocx SDKs for JavaScript, Python, PHP, Go, Java, and Ruby. Get started with document generation, deliverables, digital signatures, and quoting."
url: "https://docs.turbodocx.com/docs/SDKs"
---

# SDKs Overview

> Official TurboDocx SDKs for JavaScript, Python, PHP, Go, Java, and Ruby. Get started with document generation, deliverables, digital signatures, and quoting.

## TurboDocx SDKs

Official client libraries for the TurboDocx API. Build document generation, digital signature, and quoting workflows in your language of choice.

## Choose Your Product

All five modules ship in the **same package** for each language: pick the one that matches what you're building:

| Product | Use it when you need to… |
| :------------- | :----------------------------------------------------------------------------------------- |
| **TurboSign** | Send documents for legally-binding e-signature; track status; download signed PDFs |
| **Deliverable** | Generate documents from templates with variable injection (DOCX / PPTX / PDF output) |
| **TurboQuote** | Build sales quotes & proposals (CPQ): line items, a product/bundle catalog, price books |
| **TurboWebhooks** | Receive real-time signature events instead of polling, and verify inbound deliveries |

TurboSign, Deliverable, TurboQuote, and TurboWebhooks all use the same `TURBODOCX_API_KEY` + `TURBODOCX_ORG_ID`. See [credential requirements](#which-credentials-does-each-product-need) below.

:::tip Install with one prompt
Skip the boilerplate: use the [TurboDocx Agent Skill](https://docs.turbodocx.com/docs/SDKs/agent-skills.md) to install the SDK, configure environment variables, and generate working integration code via Claude Code, GitHub Copilot, Cursor, OpenCode, Codex CLI, or Gemini CLI:

```bash
npx skills add TurboDocx/quickstart
```
:::

## TurboSign SDKs

Send documents for legally-binding eSignatures with full audit trails.

| Language                  | Package                    | Install Command                                                      | Links                                                                                              |
| :------------------------ | :------------------------- | :------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------- |
| **JavaScript/TypeScript** | `@turbodocx/sdk`           | `npm install @turbodocx/sdk`                                         | [Docs](https://docs.turbodocx.com/docs/SDKs/turbosign.md?language=js) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/js-sdk) |
| **Python**                | `turbodocx-sdk`            | `pip install turbodocx-sdk`                                          | [Docs](https://docs.turbodocx.com/docs/SDKs/turbosign.md?language=python) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/py-sdk)     |
| **PHP**                   | `turbodocx/sdk`            | `composer require turbodocx/sdk`                                     | [Docs](https://docs.turbodocx.com/docs/SDKs/turbosign.md?language=php) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/php-sdk)       |
| **Go**                    | `github.com/TurboDocx/SDK/packages/go-sdk` | `go get github.com/TurboDocx/SDK/packages/go-sdk`                                    | [Docs](https://docs.turbodocx.com/docs/SDKs/turbosign.md?language=go) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/go-sdk)         |
| **Java**                  | `com.turbodocx:turbodocx-sdk` | [Maven Central](https://search.maven.org/artifact/com.turbodocx/turbodocx-sdk) | [Docs](https://docs.turbodocx.com/docs/SDKs/turbosign.md?language=java) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/java-sdk)     |
| **Ruby**                  | `turbodocx-sdk`            | `gem install turbodocx-sdk`                                          | [Docs](https://docs.turbodocx.com/docs/SDKs/turbosign.md?language=ruby) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/ruby-sdk) |

## TurboWebhooks SDKs

Subscribe to all 7 TurboSign signature events (`sent`, `viewed`, `recipient_signed`, `signed`, `completed`, `finalization_failed`, `voided`) and verify inbound signatures with HMAC-SHA256. Each SDK exports the full set as constants, so you never hand-write the wire strings.

| Language                  | Package         | Install Command               | Links                                                                                                  |
| :------------------------ | :-------------- | :---------------------------- | :----------------------------------------------------------------------------------------------------- |
| **JavaScript / TypeScript** | `@turbodocx/sdk` | `npm install @turbodocx/sdk` | [Docs](https://docs.turbodocx.com/docs/SDKs/webhooks.md?language=js) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/js-sdk) |
| **PHP**                   | `turbodocx/sdk` | `composer require turbodocx/sdk` | [Docs](https://docs.turbodocx.com/docs/SDKs/webhooks.md?language=php) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/php-sdk) |
| **Python**                | `turbodocx-sdk` | `pip install turbodocx-sdk` | [Docs](https://docs.turbodocx.com/docs/SDKs/webhooks.md?language=python) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/py-sdk) |
| **Go**                    | `github.com/TurboDocx/SDK/packages/go-sdk` | `go get github.com/TurboDocx/SDK/packages/go-sdk` | [Docs](https://docs.turbodocx.com/docs/SDKs/webhooks.md?language=go) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/go-sdk) |
| **Java**                  | `com.turbodocx:turbodocx-sdk` | `mvn` / `gradle` (see [docs](https://docs.turbodocx.com/docs/SDKs/webhooks.md?language=java)) | [Docs](https://docs.turbodocx.com/docs/SDKs/webhooks.md?language=java) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/java-sdk) |
| **Ruby**                  | `turbodocx-sdk` | `gem install turbodocx-sdk` | [Docs](https://docs.turbodocx.com/docs/SDKs/webhooks.md?language=ruby) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/ruby-sdk) |

For the conceptual overview (delivery retries, payload schema, dashboard configuration), see [TurboSign → Webhooks](https://docs.turbodocx.com/docs/TurboSign/Webhooks.md).

## Deliverable SDKs

Generate documents from templates with dynamic variable injection, download source files and PDFs.

| Language                  | Package                    | Install Command                                                      | Links                                                                                                                          |
| :------------------------ | :------------------------- | :------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------- |
| **JavaScript/TypeScript** | `@turbodocx/sdk`           | `npm install @turbodocx/sdk`                                         | [Docs](https://docs.turbodocx.com/docs/SDKs/deliverable.md?language=js) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/js-sdk)                 |
| **Python**                | `turbodocx-sdk`            | `pip install turbodocx-sdk`                                          | [Docs](https://docs.turbodocx.com/docs/SDKs/deliverable.md?language=python) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/py-sdk)                     |
| **PHP**                   | `turbodocx/sdk`            | `composer require turbodocx/sdk`                                     | [Docs](https://docs.turbodocx.com/docs/SDKs/deliverable.md?language=php) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/php-sdk)                       |
| **Go**                    | `github.com/TurboDocx/SDK/packages/go-sdk` | `go get github.com/TurboDocx/SDK/packages/go-sdk`                                    | [Docs](https://docs.turbodocx.com/docs/SDKs/deliverable.md?language=go) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/go-sdk)                         |
| **Java**                  | `com.turbodocx:turbodocx-sdk` | [Maven Central](https://search.maven.org/artifact/com.turbodocx/turbodocx-sdk) | [Docs](https://docs.turbodocx.com/docs/SDKs/deliverable.md?language=java) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/java-sdk)                     |
| **Ruby**                  | `turbodocx-sdk`            | `gem install turbodocx-sdk`                                          | [Docs](https://docs.turbodocx.com/docs/SDKs/deliverable.md?language=ruby) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/ruby-sdk) |

## TurboQuote SDKs

Build sales quotes and proposals programmatically: quotes and line items, a product/bundle catalog, price books, companies/contacts, and quote templates.

| Language                  | Package                    | Install Command                                                      | Links                                                                                                                          |
| :------------------------ | :------------------------- | :------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------- |
| **JavaScript/TypeScript** | `@turbodocx/sdk`           | `npm install @turbodocx/sdk`                                         | [Docs](https://docs.turbodocx.com/docs/SDKs/quote.md?language=js) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/js-sdk)                       |
| **Python**                | `turbodocx-sdk`            | `pip install turbodocx-sdk`                                          | [Docs](https://docs.turbodocx.com/docs/SDKs/quote.md?language=python) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/py-sdk)                           |
| **PHP**                   | `turbodocx/sdk`            | `composer require turbodocx/sdk`                                     | [Docs](https://docs.turbodocx.com/docs/SDKs/quote.md?language=php) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/php-sdk)                             |
| **Go**                    | `github.com/TurboDocx/SDK/packages/go-sdk` | `go get github.com/TurboDocx/SDK/packages/go-sdk`                                    | [Docs](https://docs.turbodocx.com/docs/SDKs/quote.md?language=go) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/go-sdk)                               |
| **Java**                  | `com.turbodocx:turbodocx-sdk` | [Maven Central](https://search.maven.org/artifact/com.turbodocx/turbodocx-sdk) | [Docs](https://docs.turbodocx.com/docs/SDKs/quote.md?language=java) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/java-sdk)                           |
| **Ruby**                  | `turbodocx-sdk`            | `gem install turbodocx-sdk`                                          | [Docs](https://docs.turbodocx.com/docs/SDKs/quote.md?language=ruby) [GitHub](https://github.com/TurboDocx/SDK/tree/main/packages/ruby-sdk) |

:::tip Low-code or No-code?
Check out our [n8n community node](https://www.npmjs.com/package/@turbodocx/n8n-nodes-turbodocx) for workflow automation, or get [TurboDocx Writer](https://appsource.microsoft.com/en-us/product/office/WA200007397) for Microsoft Word.
:::

---

## Quick Start

Get up and running in under 2 minutes.

### 1. Get Your Credentials

Before you begin, you'll need two things from your TurboDocx account:

- **API Access Token**: Your authentication key
- **Organization ID**: Your unique organization identifier

:::note senderEmail for TurboSign
TurboSign accepts a `senderEmail` (used as the reply-to address for signature request emails). The **JS/TS SDK enforces it client-side**: `TurboSign.configure()` throws a `ValidationError` (generic `VALIDATION_ERROR` code, not an API error code) if no `senderEmail` is supplied in configuration or via the `TURBODOCX_SENDER_EMAIL` environment variable; this check runs once at configure time, not per request. Other SDKs may differ; check each SDK's README. The **backend API itself does not require `senderEmail`** for TurboSign or TurboQuote; a request or org template with no sender falls back to a generic TurboDocx no-reply address and name and is never rejected. Deliverable and TurboWebhooks do not use `senderEmail` at all.

**TurboQuote:** there is **no `senderEmail` field on a quote request**. A sender is resolved from your organization's **quote template** (Quote Settings) when set; if none is configured, the quote falls back to a generic TurboDocx sender rather than failing. See [Prepared By & Sender Identity](https://docs.turbodocx.com/docs/TurboQuote/Prepared-By-and-Sender-Identity.md).
:::

#### Which credentials does each product need?

| Product | API key | Org ID | Also needs |
| :------------- | :----------------------------- | :------------------------- | :-------------------------------------------------------------- |
| **TurboSign** | `TURBODOCX_API_KEY` | `TURBODOCX_ORG_ID` | `TURBODOCX_SENDER_EMAIL` (required by the JS/TS SDK at configure time, reply-to for signer emails; the API itself falls back to a generic sender if omitted) |
| **Deliverable** | `TURBODOCX_API_KEY` | `TURBODOCX_ORG_ID` | None |
| **TurboQuote** | `TURBODOCX_API_KEY` | `TURBODOCX_ORG_ID` | a **Sender Email + Sender Name on the org quote template** recommended (no per-request sender field exists; falls back to a generic TurboDocx sender if not configured) |
| **TurboWebhooks** | `TURBODOCX_API_KEY` (**administrator** role, non-admin keys get 403) | `TURBODOCX_ORG_ID` | the webhook secret returned by `createWebhook`, to verify inbound events |

#### How to Get Your Credentials

1. **Login to TurboDocx**: Visit [https://www.turbodocx.com](https://www.turbodocx.com)
2. **Navigate to Settings**: Click your account avatar, then click **Settings**
3. **API Keys Section**: Open **API keys** (under **Developers**) to generate or copy your API access token
4. **Organization ID**: Copy your organization ID from the **Features and integrations** page

![TurboSign API Key](https://docs.turbodocx.com/img/turbosign/api/api-key.png)
![TurboSign Organization ID](https://docs.turbodocx.com/img/turbosign/api/org-id.png)

:::tip Keep Your Credentials Secure

- Store your API key and Organization ID as environment variables
- Never commit credentials to version control
- Rotate your API keys regularly for security
:::

### 2. Install the SDK

**JavaScript**

```bash
npm install @turbodocx/sdk
# or
yarn add @turbodocx/sdk
# or
pnpm add @turbodocx/sdk
```

**TypeScript**

```bash
npm install @turbodocx/sdk
# or
yarn add @turbodocx/sdk
# or
pnpm add @turbodocx/sdk

# TypeScript types are included in the package
```

**Python**

```bash
pip install turbodocx-sdk
# or
poetry add turbodocx-sdk
```

**PHP**

```bash
composer require turbodocx/sdk
```

**Go**

```bash
go get github.com/TurboDocx/SDK/packages/go-sdk
```

**Java**

```xml
<dependency>
    <groupId>com.turbodocx</groupId>
    <artifactId>turbodocx-sdk</artifactId>
    <version>0.9.0</version>
</dependency>
```

**Ruby**

```bash
gem install turbodocx-sdk
# or add to your Gemfile:
# gem "turbodocx-sdk"
```

### 3. Send Your First Document for Signature

**JavaScript**

```javascript
const { TurboSign } = require("@turbodocx/sdk");
// or with ES modules:
// import { TurboSign } from '@turbodocx/sdk';

// Configure with your API key
TurboSign.configure({
  apiKey: process.env.TURBODOCX_API_KEY,
  orgId: process.env.TURBODOCX_ORG_ID,
  senderEmail: process.env.TURBODOCX_SENDER_EMAIL, // required for TurboSign
});

(async () => {
  // Send a document for signature
  const result = await TurboSign.sendSignature({
    fileLink: "https://www.turbodocx.com/examples/turbodocx.pdf",
    recipients: [
      { name: "John Doe", email: "john@example.com", signingOrder: 1 },
    ],
    fields: [
      {
        type: "signature",
        page: 1,
        x: 100,
        y: 500,
        width: 200,
        height: 50,
        recipientEmail: "john@example.com",
      },
    ],
  });

  console.log(`Document sent! ID: ${result.documentId}`);
})();
```

**TypeScript**

```typescript
import { TurboSign } from "@turbodocx/sdk";

// Configure with your API key
TurboSign.configure({
  apiKey: process.env.TURBODOCX_API_KEY || "",
  orgId: process.env.TURBODOCX_ORG_ID || "",
  senderEmail: process.env.TURBODOCX_SENDER_EMAIL || "", // required for TurboSign
});

// Send a document for signature
const result = await TurboSign.sendSignature({
  fileLink: "https://www.turbodocx.com/examples/turbodocx.pdf",
  recipients: [
    { name: "John Doe", email: "john@example.com", signingOrder: 1 },
  ],
  fields: [
    {
      type: "signature",
      page: 1,
      x: 100,
      y: 500,
      width: 200,
      height: 50,
      recipientEmail: "john@example.com",
    },
  ],
});

console.log(`Document sent! ID: ${result.documentId}`);
```

**Python**

```python
import asyncio
import os
from turbodocx_sdk import TurboSign

# Configure with your API key
TurboSign.configure(
    api_key=os.environ["TURBODOCX_API_KEY"],
    org_id=os.environ["TURBODOCX_ORG_ID"],
    sender_email=os.environ["TURBODOCX_SENDER_EMAIL"]  # required for TurboSign
)

async def main():
    # Send a document for signature
    result = await TurboSign.send_signature(
        file_link="https://www.turbodocx.com/examples/turbodocx.pdf",
        recipients=[
            {"name": "John Doe", "email": "john@example.com", "signingOrder": 1}
        ],
        fields=[
            {"type": "signature", "page": 1, "x": 100, "y": 500, "width": 200, "height": 50, "recipientEmail": "john@example.com"}
        ]
    )

    print(f"Document sent! ID: {result['documentId']}")

asyncio.run(main())
```

**PHP**

```php
<?php

use TurboDocx\TurboSign;
use TurboDocx\Config\HttpClientConfig;
use TurboDocx\Types\Recipient;
use TurboDocx\Types\Field;
use TurboDocx\Types\SignatureFieldType;
use TurboDocx\Types\Requests\SendSignatureRequest;

// Configure with your API key
TurboSign::configure(new HttpClientConfig(
    apiKey: getenv('TURBODOCX_API_KEY') ?: null,
    orgId: getenv('TURBODOCX_ORG_ID') ?: null,
    senderEmail: getenv('TURBODOCX_SENDER_EMAIL') ?: null
));

// Send a document for signature
$result = TurboSign::sendSignature(
    new SendSignatureRequest(
        recipients: [
            new Recipient('John Doe', 'john@example.com', 1)
        ],
        fields: [
            new Field(
                type: SignatureFieldType::SIGNATURE,
                recipientEmail: 'john@example.com',
                page: 1,
                x: 100,
                y: 500,
                width: 200,
                height: 50
            )
        ],
        fileLink: 'https://www.turbodocx.com/examples/turbodocx.pdf'
    )
);

echo "Document sent! ID: {$result->documentId}\n";
```

**Go**

```go
package main

import (
    "context"
    "fmt"
    "log"
    "os"

    turbodocx "github.com/TurboDocx/SDK/packages/go-sdk"
)

func main() {
    // Configure with your API key
    client, err := turbodocx.NewClient(
        os.Getenv("TURBODOCX_API_KEY"),
        os.Getenv("TURBODOCX_ORG_ID"),
    )
    if err != nil {
        log.Fatal(err)
    }

    // Send a document for signature
    result, err := client.TurboSign.SendSignature(context.Background(), &turbodocx.SendSignatureRequest{
        FileLink:    "https://www.turbodocx.com/examples/turbodocx.pdf",
        SenderEmail: "contracts@acme.com", // required for TurboSign
        Recipients: []turbodocx.Recipient{
            {Name: "John Doe", Email: "john@example.com", SigningOrder: 1},
        },
        Fields: []turbodocx.Field{
            {Type: "signature", Page: 1, X: 100, Y: 500, Width: 200, Height: 50, RecipientEmail: "john@example.com"},
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Document sent! ID: %s\n", result.DocumentID)
}
```

**Java**

```java
import com.turbodocx.TurboDocxClient;
import com.turbodocx.models.*;

import java.util.Arrays;

public class Main {
    public static void main(String[] args) throws Exception {
        // Configure with your API key
        TurboDocxClient client = new TurboDocxClient.Builder()
            .apiKey(System.getenv("TURBODOCX_API_KEY"))
            .orgId(System.getenv("TURBODOCX_ORG_ID"))
            .senderEmail(System.getenv("TURBODOCX_SENDER_EMAIL")) // required for TurboSign
            .build();

        // Send a document for signature
        SendSignatureResponse result = client.turboSign().sendSignature(
            new SendSignatureRequest.Builder()
                .fileLink("https://www.turbodocx.com/examples/turbodocx.pdf")
                .recipients(Arrays.asList(
                    new Recipient("John Doe", "john@example.com", 1)
                ))
                .fields(Arrays.asList(
                    new Field("signature", 1, 100, 500, 200, 50, "john@example.com")
                ))
                .build()
        );

        System.out.println("Document sent! ID: " + result.getDocumentId());
    }
}
```

**Ruby**

```ruby
require "turbodocx_sdk"

# Configure with your API key
TurboDocxSdk::TurboSign.configure(
  api_key:      ENV["TURBODOCX_API_KEY"],
  org_id:       ENV["TURBODOCX_ORG_ID"],
  sender_email: ENV["TURBODOCX_SENDER_EMAIL"]  # required for TurboSign
)

# Send a document for signature
result = TurboDocxSdk::TurboSign.send_signature(
  fileLink: "https://www.turbodocx.com/examples/turbodocx.pdf",
  recipients: [
    { name: "John Doe", email: "john@example.com", signingOrder: 1 }
  ],
  fields: [
    { type: "signature", page: 1, x: 100, y: 500, width: 200, height: 50, recipientEmail: "john@example.com" }
  ]
)

puts "Document sent! ID: #{result['documentId']}"
```

---

## Core Features

All TurboDocx SDKs provide access to:

### TurboSign: Digital Signatures

Send documents for legally-binding eSignatures with full audit trails.

| Method                        | Description                                             |
| :---------------------------- | :------------------------------------------------------ |
| `createSignatureReviewLink()` | Upload document for preview without sending emails      |
| `sendSignature()`             | Upload and immediately send signature requests          |
| `getStatus()`                 | Check the document-level status                         |
| `getRecipients()`             | Per-signer status, email history, and who sent it       |
| `download()`                  | Download the completed signed document                  |
| `void()`                      | Cancel/void a signature request                         |
| `resend()`                    | Resend signature request emails                         |
| `getAuditTrail()`             | Get complete audit trail with all events and timestamps |
| `getTemplateSignatureSetup()` | List a template's signer roles, to send it by role      |

[Learn more about TurboSign →](https://docs.turbodocx.com/docs/TurboSign/Setting-up-TurboSign.md)

### Deliverable: Document Generation

Generate documents from templates with dynamic variable injection, download source files and PDFs.

| Method                      | Description                                                |
| :-------------------------- | :--------------------------------------------------------- |
| `generateDeliverable()`     | Generate a document from a template with variable injection |
| `listDeliverables()`        | List deliverables with pagination, search, and filtering   |
| `getDeliverableDetails()`   | Get full details of a deliverable including variables      |
| `updateDeliverableInfo()`   | Update a deliverable's name, description, or tags          |
| `deleteDeliverable()`       | Soft-delete a deliverable                                  |
| `downloadSourceFile()`      | Download the original DOCX/PPTX source file                |
| `downloadPDF()`             | Download the PDF version                                   |

[Learn more about Deliverable SDKs →](https://docs.turbodocx.com/docs/SDKs/deliverable.md?language=js)

### TurboQuote: Sales Quoting & CPQ

Build quotes and proposals: line items, a product/bundle catalog, price books, companies, and contacts.

| Method                       | Description                                                        |
| :--------------------------- | :---------------------------------------------------------------- |
| `createQuote()`              | Create a draft quote for a company and contact                    |
| `addLineItems()`             | Add product or bundle line items to a quote                       |
| `sendQuote()`                | Send a quote to the customer for review                           |
| `sendQuoteWithDeliverable()` | Merge a TurboDocx Deliverable with the quote and send for e-signature |
| `downloadQuotePdf()`         | Download the rendered quote PDF                                    |
| `createProduct()` / `createBundle()` / `createPriceBook()` | Manage the product catalog and pricing |
| `createAndSend()`            | Create, add line items, and send in a single call                 |

[Learn more about TurboQuote SDKs →](https://docs.turbodocx.com/docs/SDKs/quote.md?language=js)

### TurboWebhooks: Signature Events

Subscribe a per-org endpoint to TurboSign events and verify inbound deliveries with HMAC-SHA256. **Requires an administrator API key.**

| Method                       | Description                                                       |
| :--------------------------- | :--------------------------------------------------------------- |
| `createWebhook()`            | Subscribe the org's `signature` webhook (returns the secret once) |
| `getWebhook()`               | Get the webhook plus delivery stats                              |
| `updateWebhook()`            | Update URLs, events, or active state                            |
| `testWebhook()`              | Fire a synthetic delivery to all configured URLs                |
| `regenerateWebhookSecret()`  | Rotate the HMAC secret                                          |
| `listWebhookDeliveries()` / `replayWebhookDelivery()` | Inspect and retry past deliveries        |
| `verifyWebhookSignature()`   | Free function, verify the `X-TurboDocx-Signature` header on a received event |

[Learn more about TurboWebhooks SDKs →](https://docs.turbodocx.com/docs/SDKs/webhooks.md?language=js)

---

## Field Positioning

TurboSign supports two methods for placing signature fields on your documents:

| Method               | Best For                                                                 |
| :------------------- | :----------------------------------------------------------------------- |
| **Coordinate-Based** | PDFs with fixed layouts where you know exact pixel positions             |
| **Template-Based**   | Documents where content may shift, using text anchors like `{SIGNATURE}` |

:::info Field Positioning Reference
For detailed information about both positioning methods, including anchor configuration, placement options, and best practices, see the **[Field Positioning Methods](https://docs.turbodocx.com/docs/TurboSign/API-Signatures.md#field-positioning-methods)** guide.
:::

:::info Complete Field Types Reference
For a comprehensive list of all available field types (signature, initials, text, date, checkbox, full_name, email, title, company) and their detailed usage, see the [Field Types section in the API Signatures guide](https://docs.turbodocx.com/docs/TurboSign/API-Signatures.md#field-types-reference).
:::

---

## Error Handling

All SDKs provide structured error handling with detailed error codes:

**JavaScript**

```javascript
const { TurboSign, TurboDocxError } = require("@turbodocx/sdk");

(async () => {
  try {
    const result = await TurboSign.sendSignature({
      /* ... */
    });
  } catch (error) {
    if (error instanceof TurboDocxError) {
      console.error(`Error ${error.code}: ${error.message}`);
      // Handle specific error codes
      if (error.code === "VALIDATION_ERROR") {
        // Handle validation error
      }
    }
  }
})();
```

**TypeScript**

```typescript
import { TurboSign, TurboDocxError } from "@turbodocx/sdk";

try {
  const result = await TurboSign.sendSignature({
    /* ... */
  });
} catch (error) {
  if (error instanceof TurboDocxError) {
    console.error(`Error ${error.code}: ${error.message}`);
    // Handle specific error codes
    if (error.code === "VALIDATION_ERROR") {
      // Handle validation error
    }
  }
}
```

**Python**

```python
import asyncio
from turbodocx_sdk import TurboSign, TurboDocxError

async def main():
    try:
        result = await TurboSign.send_signature(...)
    except TurboDocxError as e:
        # TurboDocxError doesn't set a .message attribute; str(e) is the message
        print(f"Error {e.code}: {e}")
        if e.code == "VALIDATION_ERROR":
            # Handle validation error
            pass

asyncio.run(main())
```

**PHP**

```php
<?php

use TurboDocx\TurboSign;
use TurboDocx\Exceptions\TurboDocxException;
use TurboDocx\Exceptions\ValidationException;

try {
    $result = TurboSign::sendSignature(/* ... */);
} catch (ValidationException $e) {
    echo "Validation error: {$e->getMessage()}\n";
    // Handle validation error
} catch (TurboDocxException $e) {
    echo "Error {$e->errorCode}: {$e->getMessage()}\n";
    echo "Status code: {$e->statusCode}\n";
}
```

**Go**

```go
result, err := client.TurboSign.SendSignature(ctx, request)
if err != nil {
    // errors.As must target the specific type: a *TurboDocxError target does not match
    // *ValidationError, *AuthenticationError, etc., even though each embeds TurboDocxError.
    // See the Go SDK's own Error Handling reference for the full set of named types.
    var validationErr *sdk.ValidationError
    if errors.As(err, &validationErr) {
        fmt.Printf("Validation error [%s]: %s\n", validationErr.Code, validationErr.Message)
    }
}
```

**Java**

```java
import com.turbodocx.TurboDocxException;
import com.turbodocx.TurboDocxException.*;
import com.turbodocx.models.*;

try {
    SendSignatureResponse result = client.turboSign().sendSignature(/* ... */);
} catch (AuthenticationException e) {
    System.err.println("Invalid API key: " + e.getMessage());
} catch (ValidationException e) {
    System.err.println("Validation error: " + e.getMessage());
    System.err.println("Error code: " + e.getCode());
} catch (RateLimitException e) {
    System.err.println("Rate limited: " + e.getMessage());
} catch (TurboDocxException e) {
    System.err.println("Error " + e.getCode() + ": " + e.getMessage());
    System.err.println("Status code: " + e.getStatusCode());
}
```

**Ruby**

```ruby
require "turbodocx_sdk"

begin
  result = TurboDocxSdk::TurboSign.send_signature(
    # ...
  )
rescue TurboDocxSdk::ValidationError => e
  puts "Validation error: #{e.message}"
  # Handle validation error
rescue TurboDocxSdk::TurboDocxError => e
  puts "Error #{e.code}: #{e.message}"
  puts "Status code: #{e.status_code}"
end
```

### Common Error Codes

| Code                   | HTTP Status | Description                           |
| :--------------------- | :---------- | :------------------------------------ |
| `AUTHENTICATION_ERROR` | 401         | Invalid or expired API key            |
| `AUTHORIZATION_ERROR`  | 403         | Authenticated, but lacks permission   |
| `VALIDATION_ERROR`     | 400         | Invalid request data or parameters    |
| `NOT_FOUND`            | 404         | Document or resource not found        |
| `CONFLICT`             | 409         | Conflicts with the resource's state   |
| `RATE_LIMIT_EXCEEDED`  | 429         | Too many requests, retry with backoff |
| `NETWORK_ERROR`        | N/A         | Network connection or timeout error   |

When the API returns a specific code the SDK surfaces it verbatim; otherwise, for one of the
7 named categories above, it falls back to that class's default, so `code` is populated for
those without a null check. An error for a status code outside this table (an unexpected 5xx,
for example) is not guaranteed a `code`.

### TurboQuote / TurboSign specific codes

These are returned by the API and passed through unchanged. They are more precise than the
generic codes above; prefer them when handling a specific failure.

| Code                       | HTTP Status | Meaning                                                                                     |
| :------------------------- | :---------- | :------------------------------------------------------------------------------------------ |
| `QuoteHasNoLineItems`      | 400         | The quote has no line items. Add at least one product, bundle, or custom line item.          |
| `QuoteExpired`             | 400         | The quote is past its `validUntil` date. Update the date before sending.                     |
| `QuoteValidUntilRequired`  | 400         | The quote has no `validUntil` date set.                                                      |
| `QuoteNotSendable`         | 400         | The quote's current status does not allow sending (only drafts can be sent).                 |
| `QuoteContactRequired`     | 400         | The quote's contact is missing a name or email.                                              |
| `QuoteCustomerInactive`    | 400         | The quote's company or contact was deleted or deactivated.                                   |
| `QUOTE_NOT_FOUND`          | 404         | No quote with that ID in this organization.                                                  |

### Error messages carry the actionable reason

The API reports validation failures in several envelopes. The SDKs unwrap all of them, so
`error.message` is the specific field-level reason, not a generic
`"There was an issue validating the body"`. Multiple field errors are joined with `"; "`:

```
"name" is not allowed to be empty; "companyId" must be a valid GUID
```

---

## Audit Trail & Client Context

Every action you take through an SDK is recorded in the TurboDocx audit trail. All six SDKs
automatically attach **client-context headers** to **every** request, including TurboSign,
Deliverable, TurboQuote, TurboWebhooks, and TurboPartner, so the audit trail records real
environment details instead of blanks:

| Recorded column | What the SDK sends |
| :--- | :--- |
| **Device** | The host machine / runtime the call came from |
| **Operating system** | The OS the SDK is running on |
| **Timezone** | The machine's IANA timezone (e.g. `America/New_York`) |
| **Language** | The machine's locale (e.g. `en-US`) |
| **Application** | `TurboDocx SDK <version>` |

You do not configure any of this: it is collected and sent for you.

### SDK / n8n calls vs. raw API calls

The audit trail distinguishes how a request reached TurboDocx:

| Caller | How it appears in the audit trail |
| :--- | :--- |
| A language SDK | `TurboDocx SDK <version>`, with real device, OS, timezone, and language |
| The TurboDocx n8n node | `TurboDocx n8n Node <version>`, with real device, OS, timezone, and language |
| A raw HTTP/API call | The **name of the HTTP library** that made the call, the action `API Request`, and `N/A` for the environment fields it cannot know |

Raw API calls show `N/A` (not `Unknown`) for the fields no client context was supplied for. If
you want fully attributed audit entries, call through an SDK or the n8n node rather than hand-rolled
HTTP.

---

## Next Steps

API Signatures

Complete guide to TurboSign API integration with detailed examples.

          View Guide →

Webhooks

Receive real-time notifications when documents are signed.

          View Webhooks →

GitHub Repository

View source code, report issues, and contribute to the SDKs.

          View on GitHub →

---

## Support

Need help with the SDKs?

- **Discord Community**: [Join our Discord](https://discord.gg/NYKwz4BcpX) for real-time support
- **GitHub Issues**: [Report bugs or request features](https://github.com/TurboDocx/SDK/issues)
- **Documentation**: Browse the language-specific guides in the sidebar
