Skip to main content

TurboSign PHP SDK

Agent Skill

Let an agent scaffold this for you

Install the TurboDocx Quickstart Skill and let Claude Code, Cursor, Copilot, Codex, or any agent that speaks the Agent Skills standard install the SDK, wire it into your app, and write a working TurboSign integration end-to-end.

bash — turbodocx
$npx skills add TurboDocx/quickstart
# then, inside your agent:›/turbodocx-sdk turbosign

The official TurboDocx SDK for PHP applications. Build document generation and digital signature workflows with modern PHP 8.1+ features, strong typing, and comprehensive error handling. Available on Packagist as turbodocx/sdk.

Installation​

composer require turbodocx/sdk

Requirements​

  • PHP 8.1 or higher
  • Composer
  • ext-json
  • ext-fileinfo
Modern PHP Features

This SDK leverages PHP 8.1+ features including enums, named parameters, readonly classes, and match expressions for a superior developer experience.


Configuration​

<?php

use TurboDocx\TurboSign;
use TurboDocx\Config\HttpClientConfig;

// Configure with all options
TurboSign::configure(new HttpClientConfig(
apiKey: $_ENV['TURBODOCX_API_KEY'], // Required: Your TurboDocx API key
orgId: $_ENV['TURBODOCX_ORG_ID'], // Required: Your organization ID
senderEmail: $_ENV['TURBODOCX_SENDER_EMAIL'], // Required: Reply-to email for signature requests
senderName: $_ENV['TURBODOCX_SENDER_NAME'], // Optional: Sender name (strongly recommended)
baseUrl: 'https://api.turbodocx.com' // Optional: Custom API endpoint
));
Sender Email Required

The senderEmail parameter is required for TurboSign. This email appears as the reply-to address in signature request emails. If you omit it, configure() throws a ValidationException before any request is sent (unless skipSenderValidation is enabled, which TurboSign does not use).

Environment Variables​

# .env
TURBODOCX_API_KEY=your_api_key_here
TURBODOCX_ORG_ID=your_org_id_here
TURBODOCX_SENDER_EMAIL=you@company.com
TURBODOCX_SENDER_NAME=Your Company Name
API Credentials Required

Both apiKey and orgId parameters are required for all API requests. To get your credentials, follow the Get Your Credentials steps from the SDKs main page.


Quick Start​

Send a Document for Signature​

<?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;

TurboSign::configure(HttpClientConfig::fromEnvironment());

// Send document with coordinate-based fields
$result = TurboSign::sendSignature(
new SendSignatureRequest(
recipients: [
new Recipient('Alice Smith', 'alice@example.com', 1),
new Recipient('Bob Johnson', 'bob@example.com', 2)
],
fields: [
// Alice's signature
new Field(
type: SignatureFieldType::SIGNATURE,
recipientEmail: 'alice@example.com',
page: 1,
x: 100,
y: 650,
width: 200,
height: 50
),
new Field(
type: SignatureFieldType::DATE,
recipientEmail: 'alice@example.com',
page: 1,
x: 320,
y: 650,
width: 100,
height: 30,
defaultValue: '12/31/2026' // Pins a fixed date in MM/DD/YYYY; omit to auto-fill the signing date
),
// Bob's signature
new Field(
type: SignatureFieldType::SIGNATURE,
recipientEmail: 'bob@example.com',
page: 1,
x: 100,
y: 720,
width: 200,
height: 50
),
new Field(
type: SignatureFieldType::DATE,
recipientEmail: 'bob@example.com',
page: 1,
x: 320,
y: 720,
width: 100,
height: 30
)
],
fileLink: 'https://www.turbodocx.com/examples/turbodocx.pdf',
documentName: 'Service Agreement',
senderName: 'Acme Corp',
senderEmail: 'contracts@acme.com'
)
);

echo "Document ID: {$result->documentId}\n";
Always Handle Errors

The above examples omit error handling for brevity. In production, wrap all TurboSign calls in try-catch blocks. See Error Handling for complete patterns.

Using Template-Based Fields​

<?php

use TurboDocx\Types\Recipient;
use TurboDocx\Types\Field;
use TurboDocx\Types\SignatureFieldType;
use TurboDocx\Types\Requests\SendSignatureRequest;
use TurboDocx\Types\TemplateConfig;
use TurboDocx\Types\FieldPlacement;

$result = TurboSign::sendSignature(
new SendSignatureRequest(
recipients: [
new Recipient('Alice Smith', 'alice@example.com', 1)
],
fields: [
new Field(
type: SignatureFieldType::SIGNATURE,
recipientEmail: 'alice@example.com',
template: new TemplateConfig(
anchor: '{SIGNATURE_ALICE}',
placement: FieldPlacement::REPLACE,
size: ['width' => 200, 'height' => 50]
)
),
new Field(
type: SignatureFieldType::DATE,
recipientEmail: 'alice@example.com',
template: new TemplateConfig(
anchor: '{DATE_ALICE}',
placement: FieldPlacement::REPLACE,
size: ['width' => 100, 'height' => 30]
)
)
],
fileLink: 'https://www.turbodocx.com/examples/turbodocx.pdf',
senderName: 'Your Company',
senderEmail: 'sender@company.com'
)
);
Always Handle Errors

The above examples omit error handling for brevity. In production, wrap all TurboSign calls in try-catch blocks. See Error Handling for complete patterns.

Template Anchors Required

Important: The document file must contain the anchor text (e.g., {SIGNATURE_ALICE}, {DATE_ALICE}) that you reference in your fields. If the anchors don't exist in the document, the API will return an error.


File Input Methods​

TurboSign supports four different ways to provide document files:

1. File Upload (Direct)​

<?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;

TurboSign::configure(HttpClientConfig::fromEnvironment());

$pdfContent = file_get_contents('./contract.pdf');

$result = TurboSign::sendSignature(
new SendSignatureRequest(
file: $pdfContent,
fileName: 'contract.pdf', // Optional
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
)
]
)
);

2. File URL​

<?php

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

$result = TurboSign::sendSignature(
new SendSignatureRequest(
fileLink: 'https://www.turbodocx.com/examples/turbodocx.pdf',
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
)
]
)
);
When to use fileLink

Use fileLink when your documents are already hosted on cloud storage (S3, Google Cloud Storage, etc.). This is more efficient than downloading and re-uploading files.

3. TurboDocx Deliverable ID​

<?php

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

// Use a previously generated TurboDocx document
$result = TurboSign::sendSignature(
new SendSignatureRequest(
deliverableId: 'deliverable-uuid-from-turbodocx',
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
)
]
)
);
Integration with TurboDocx

deliverableId references documents generated using TurboDocx's document generation API. This creates a seamless workflow: generate → sign.

4. TurboDocx Template ID​

<?php

use TurboDocx\TurboSign;
use TurboDocx\Types\Recipient;
use TurboDocx\Types\Field;
use TurboDocx\Types\SignatureFieldType;
use TurboDocx\Types\Requests\SendSignatureRequest;
use TurboDocx\Types\TemplateConfig;
use TurboDocx\Types\FieldPlacement;

// Use a pre-configured TurboSign template
$result = TurboSign::sendSignature(
new SendSignatureRequest(
templateId: 'template-uuid-from-turbodocx',
recipients: [
new Recipient('Alice Smith', 'alice@example.com', 1)
],
fields: [
new Field(
type: SignatureFieldType::SIGNATURE,
recipientEmail: 'alice@example.com',
template: new TemplateConfig(
anchor: '{SIGNATURE_ALICE}',
placement: FieldPlacement::REPLACE,
size: ['width' => 200, 'height' => 50]
)
)
]
)
);
Integration with TurboDocx

templateId references pre-configured TurboSign templates created in the TurboDocx dashboard. These templates come with built-in anchors and field positioning, making it easy to reuse signature workflows across multiple documents.


API Reference​

Configure​

Configure the SDK with your API credentials and organization settings.

use TurboDocx\TurboSign;
use TurboDocx\Config\HttpClientConfig;

// Manual configuration
TurboSign::configure(new HttpClientConfig(
apiKey: 'your-api-key',
orgId: 'your-org-id',
senderEmail: 'you@company.com',
senderName: 'Your Company'
));

// Or from environment
TurboSign::configure(HttpClientConfig::fromEnvironment());

Prepare for review​

Upload a document for preview without sending signature request emails.

use TurboDocx\Types\Recipient;
use TurboDocx\Types\Field;
use TurboDocx\Types\SignatureFieldType;
use TurboDocx\Types\Requests\CreateSignatureReviewLinkRequest;

$result = TurboSign::createSignatureReviewLink(
new CreateSignatureReviewLinkRequest(
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',
documentName: 'Contract Draft'
)
);

echo "Preview URL: {$result->previewUrl}\n";
echo "Document ID: {$result->documentId}\n";

Prepare for signing​

Upload a document and immediately send signature requests to all recipients.

use TurboDocx\Types\Recipient;
use TurboDocx\Types\Field;
use TurboDocx\Types\SignatureFieldType;
use TurboDocx\Types\Requests\SendSignatureRequest;

$result = TurboSign::sendSignature(
new SendSignatureRequest(
recipients: [
new Recipient('Recipient Name', 'recipient@example.com', 1)
],
fields: [
new Field(
type: SignatureFieldType::SIGNATURE,
recipientEmail: 'recipient@example.com',
page: 1,
x: 100,
y: 500,
width: 200,
height: 50
)
],
fileLink: 'https://www.turbodocx.com/examples/turbodocx.pdf',
documentName: 'Service Agreement'
)
);

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

Reminders and expiration​

sendSignature can also schedule automatic reminder emails and an expiration deadline. All eight schedule fields are optional and both features are off by default, so omitting them preserves the original send behavior. The resolved schedule is frozen onto the document when it is sent: changing your org defaults later never alters a document already out for signature.

use TurboDocx\Types\Requests\SendSignatureRequest;

$result = TurboSign::sendSignature(
new SendSignatureRequest(
// ...recipients, fields, fileLink, documentName
remindersEnabled: true,
reminderDelay: ['value' => 3, 'unit' => 'days'], // time to the FIRST reminder
reminderInterval: ['value' => 3, 'unit' => 'days'], // gap between later reminders
maxReminders: 5, // -1 unlimited, 0 none, max 50 (default 5)
expirationEnabled: true,
expireAfter: ['value' => 30, 'unit' => 'days'], // how long the document stays signable
expirationWarning: ['value' => 3, 'unit' => 'days'], // 0 = never warn
expirationWarningInterval: ['value' => 1, 'unit' => 'days']
)
);

Durations are ['value' => N, 'unit' => 'hours'|'days'] objects. value is a whole number from 1 up to a maximum of 999 days (23976 hours); expirationWarning also accepts 0 to disable warnings. maxReminders accepts -1 (unlimited), 0 (none), or any value up to 50. The resulting deadline is readable afterwards via getStatus()->expiresAt.

Send a reminder​

Send a standalone reminder to whoever's turn it is to sign (POST /turbosign/documents/{documentId}/send-reminder). It is independent of the automatic cadence: it works even when reminders are disabled or the per-signer cap is already spent, does not consume that cap, and only emails signers at the current signing order. Pass null (or omit the argument) to remind everyone eligible; do not pass an empty array, which the API rejects.

// Remind everyone whose turn it is to sign.
$result = TurboSign::sendReminder('document-uuid');

foreach ($result['results'] as $r) {
// 'sent', 'skipped_wrong_order', 'skipped_completed', ...
echo "{$r['recipientId']}: {$r['status']}\n";
}

// Or limit to specific recipients (all-or-nothing): every id must be a current-order pending signer.
TurboSign::sendReminder('document-uuid', ['recipient-uuid-1', 'recipient-uuid-2']);

Get status​

Retrieve the current status of a document. When expiration is enabled, the response also carries the signing-window deadline as expiresAt; once that instant passes the document reaches the terminal expired status. The same expiresAt is available on the document returned by getRecipients(). For per-signer detail, use Get recipients.

$status = TurboSign::getStatus('document-uuid');

echo "Document Status: {$status->status}\n"; // 'under_review', 'completed', 'voided', 'expired'
// expiresAt is the signing-window deadline (ISO 8601), or null when expiration is off.
echo "Expires: " . ($status->expiresAt ?? 'never') . "\n";

Get recipients​

See who the document went to, who has signed, who you are still waiting on, and who sent it.

$progress = TurboSign::getRecipients('document-uuid');

echo "{$progress->summary->completed}/{$progress->summary->total} signed, ";
echo "waiting on {$progress->summary->waitingOn}\n";

foreach ($progress->recipients as $r) {
echo " {$r->name} <{$r->email}>: {$r->effectiveStatus}";
echo " (emailed {$r->delivery->totalSent}x)\n";
}
Two status fields, and they differ on purpose

status is the raw database value and is only ever pending, viewed or completed. effectiveStatus layers the document's outcome on top, adding voided and expired: that is the one to display.

On a voided or expired document an unsigned signer still reads pending in status, so branching on it would show someone as "still to sign" when their signing link is already dead. A completed signature is never revoked: someone who signed before the document was voided still reads completed.

summary counts by effectiveStatus, and waitingOn (pending + viewed) drops to zero once the document is terminal.

Each recipient also carries a delivery block: firstSentOn, lastSentOn, totalSent, reminderCount, lastRemindedAt, warningCount, lastWarningAt. It counts the signature request, resends, reminders, expiry warnings and terminal notices; CC notifications are excluded, since a CC address is not a signer.

reminderCount and lastRemindedAt do not mean what their names suggest

reminderCount counts automatic (scheduled) reminders only: the counter maxReminders caps. A manual "remind now" is a standalone nudge that must not consume the cap budget, so it does not increment this, even though the email it sends does appear in totalSent.

lastRemindedAt is a cadence clock, not a record of a reminder: the initial signature-request send, each scheduled reminder, each manual "remind now" and each expiry warning all stamp it. Only scheduled reminders bump reminderCount.

So a freshly-sent document returns a non-null lastRemindedAt equal to the invitation timestamp alongside reminderCount: 0: nobody has been reminded. To answer "have we actually chased this person", read totalSent, not reminderCount.

warningCount / lastWarningAt have no such caveat.

Download document​

Download the completed signed document as PDF content.

$pdfContent = TurboSign::download('document-uuid');

// Save to file
file_put_contents('signed-contract.pdf', $pdfContent);

// Or send as HTTP response
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="signed.pdf"');
echo $pdfContent;

Void​

Cancel/void a signature request that hasn't been completed.

use TurboDocx\Types\Responses\VoidDocumentResponse;

$result = TurboSign::void('document-uuid', 'Document needs to be revised');

echo "Document ID: {$result->id}\n";
echo "Status: {$result->status}\n";
echo "Void Reason: {$result->voidReason}\n";

Resend​

Resend signature request emails to specific recipients.

// Resend to specific recipients
$result = TurboSign::resend('document-uuid', ['recipient-id-1', 'recipient-id-2']);

// Resend to all recipients
$result = TurboSign::resend('document-uuid', []);

echo "Recipients notified: {$result->recipientCount}\n";

Get audit trail​

Retrieve the complete audit trail for a document, including all events and actions.

$audit = TurboSign::getAuditTrail('document-uuid');

echo "Audit Trail:\n";
foreach ($audit->auditTrail as $entry) {
echo " {$entry->timestamp} - {$entry->actionType}";
if ($entry->user) {
echo " by {$entry->user->name}";
}
echo "\n";
}

Field Types​

TurboSign supports 11 different field types using PHP enums:

use TurboDocx\Types\SignatureFieldType;

SignatureFieldType::SIGNATURE // Signature field
SignatureFieldType::INITIAL // Initial field
SignatureFieldType::DATE // Date stamp (auto-filled when signed)
SignatureFieldType::TEXT // Free text input
SignatureFieldType::FULL_NAME // Full name (auto-filled from recipient)
SignatureFieldType::FIRST_NAME // First name
SignatureFieldType::LAST_NAME // Last name
SignatureFieldType::EMAIL // Email address
SignatureFieldType::TITLE // Job title
SignatureFieldType::COMPANY // Company name
SignatureFieldType::CHECKBOX // Checkbox field

Field Positioning​

TurboSign supports two ways to position fields:

1. Coordinate-Based (Pixel Perfect)​

new Field(
type: SignatureFieldType::SIGNATURE,
recipientEmail: 'john@example.com',
page: 1, // Page number (1-indexed)
x: 100, // X coordinate
y: 500, // Y coordinate
width: 200, // Width in pixels
height: 50 // Height in pixels
)

2. Template Anchors (Dynamic)​

use TurboDocx\Types\TemplateConfig;
use TurboDocx\Types\FieldPlacement;

new Field(
type: SignatureFieldType::SIGNATURE,
recipientEmail: 'john@example.com',
template: new TemplateConfig(
anchor: '{signature1}', // Text to find in PDF
placement: FieldPlacement::REPLACE, // How to place the field
size: ['width' => 100, 'height' => 30]
)
)

Placement Options:

  • FieldPlacement::REPLACE - Replace the anchor text
  • FieldPlacement::BEFORE - Place before the anchor
  • FieldPlacement::AFTER - Place after the anchor
  • FieldPlacement::ABOVE - Place above the anchor
  • FieldPlacement::BELOW - Place below the anchor

Advanced Field Options​

// Checkbox (pre-checked, readonly)
new Field(
type: SignatureFieldType::CHECKBOX,
recipientEmail: 'john@example.com',
page: 1,
x: 100,
y: 600,
width: 20,
height: 20,
defaultValue: 'true', // Pre-checked
isReadonly: true // Cannot be unchecked
)

// Multiline text field
new Field(
type: SignatureFieldType::TEXT,
recipientEmail: 'john@example.com',
page: 1,
x: 100,
y: 200,
width: 400,
height: 100,
isMultiline: true, // Allow multiple lines
required: true, // Field is required
backgroundColor: '#f0f0f0' // Background color
)

// Readonly text (pre-filled, non-editable)
new Field(
type: SignatureFieldType::TEXT,
recipientEmail: 'john@example.com',
page: 1,
x: 100,
y: 300,
width: 300,
height: 30,
defaultValue: 'This text is pre-filled',
isReadonly: true
)

Conditional (IF/THEN) Fields​

The optional metadata builds IF/THEN relationships between fields. Put a fieldKey on a controlling checkbox, then point each dependent field's controllingFieldKey back at it.

use TurboDocx\Types\FieldMetadata;
use TurboDocx\Types\FieldConditional;
use TurboDocx\Types\ConditionalOperator;
use TurboDocx\Types\ConditionalAction;

// Controlling checkbox, carries a stable fieldKey
new Field(
type: SignatureFieldType::CHECKBOX,
recipientEmail: 'reviewer@company.com',
page: 1,
x: 100,
y: 400,
width: 20,
height: 20,
metadata: new FieldMetadata(fieldKey: 'request_changes')
);

// Dependent text field, hidden until the checkbox is checked
new Field(
type: SignatureFieldType::TEXT,
recipientEmail: 'reviewer@company.com',
page: 1,
x: 130,
y: 400,
width: 300,
height: 60,
metadata: new FieldMetadata(
conditional: new FieldConditional(
controllingFieldKey: 'request_changes', // = the checkbox's fieldKey
operator: ConditionalOperator::IS_CHECKED, // ::IS_CHECKED | ::IS_NOT_CHECKED
action: ConditionalAction::SHOW // ::SHOW | ::UNLOCK
)
)
);

Use action: 'unlock' to keep a field visible but read-only until the box is checked. A malformed rule returns 400 InvalidConditionalRule; a well-formed rule whose controllingFieldKey matches no checkbox fails open (the field stays visible/editable). See Conditional (IF/THEN) Fields.


Error Handling​

Every typed exception extends TurboDocxException, itself a plain Exception subclass with two extra readonly properties: statusCode (int, HTTP status) and errorCode (string, e.g. 'VALIDATION_ERROR'). Because the constructor hardcodes PHP's built-in Exception::getCode() to 0, read $e->errorCode, not $e->getCode(), for the machine-readable reason:

use TurboDocx\Exceptions\AuthenticationException;
use TurboDocx\Exceptions\AuthorizationException;
use TurboDocx\Exceptions\ValidationException;
use TurboDocx\Exceptions\NotFoundException;
use TurboDocx\Exceptions\ConflictException;
use TurboDocx\Exceptions\RateLimitException;
use TurboDocx\Exceptions\NetworkException;

try {
$result = TurboSign::sendSignature(/* ... */);
} catch (AuthenticationException $e) {
// 401 - Invalid API key or access token
echo "Authentication failed: {$e->getMessage()}\n";
} catch (AuthorizationException $e) {
// 403 - Valid credentials without permission for this operation
echo "Authorization error: {$e->getMessage()}\n";
} catch (ValidationException $e) {
// 400 - Invalid request data
echo "Validation error: {$e->getMessage()}\n";
} catch (NotFoundException $e) {
// 404 - Document not found
echo "Not found: {$e->getMessage()}\n";
} catch (ConflictException $e) {
// 409 - Conflicts with the current resource state
echo "Conflict: {$e->getMessage()}\n";
} catch (RateLimitException $e) {
// 429 - Rate limit exceeded
echo "Rate limit: {$e->getMessage()}\n";
} catch (NetworkException $e) {
// Network/connection error
echo "Network error: {$e->getMessage()}\n";
} catch (TurboDocxException $e) {
// Catch-all: read the machine-readable reason from errorCode, not getCode()
echo "Error {$e->errorCode}: {$e->getMessage()} (status {$e->statusCode})\n";
}

Error Classes​

Error ClassStatus CodeDescription
TurboDocxExceptionvariesBase exception for all SDK errors
AuthenticationException401Invalid or missing API credentials
AuthorizationException403Valid credentials without permission for this operation
ValidationException400Invalid request parameters
NotFoundException404Document or resource not found
ConflictException409Request conflicts with current resource state
RateLimitException429Too many requests
NetworkException-Network connectivity issues

All exceptions extend TurboDocxException and include:

  • getMessage() - Human-readable error message
  • statusCode - HTTP status code, a public readonly ?int (null for NetworkException)
  • errorCode - Error code string (e.g., 'AUTHENTICATION_ERROR'), a public readonly ?string

PHP Types​

Enums​

The SDK uses PHP 8.1+ enums for type safety:

// Field types
enum SignatureFieldType: string {
case SIGNATURE = 'signature';
case INITIAL = 'initial';
case DATE = 'date';
case TEXT = 'text';
case FULL_NAME = 'full_name';
case FIRST_NAME = 'first_name';
case LAST_NAME = 'last_name';
case EMAIL = 'email';
case TITLE = 'title';
case COMPANY = 'company';
case CHECKBOX = 'checkbox';
}

// Field placement
enum FieldPlacement: string {
case REPLACE = 'replace';
case BEFORE = 'before';
case AFTER = 'after';
case ABOVE = 'above';
case BELOW = 'below';
}

// Document status
enum DocumentStatus: string {
case DRAFT = 'draft';
case SETUP_COMPLETE = 'setup_complete';
case REVIEW_READY = 'review_ready';
case UNDER_REVIEW = 'under_review';
case COMPLETED = 'completed';
case VOIDED = 'voided';
}

// Conditional (IF/THEN) operator, the condition evaluated against the controlling checkbox
enum ConditionalOperator: string {
case IS_CHECKED = 'is_checked';
case IS_NOT_CHECKED = 'is_not_checked';
}

// Conditional (IF/THEN) action, what happens to the dependent field until the condition is met
enum ConditionalAction: string {
case SHOW = 'show'; // hidden until met
case UNLOCK = 'unlock'; // visible but read-only until met
}

Readonly Classes​

The SDK uses readonly classes with typed properties:

final class Recipient {
public function __construct(
public string $name,
public string $email,
public int $signingOrder
) {}
}

final class Field {
public function __construct(
public SignatureFieldType $type,
public string $recipientEmail,
public ?int $page = null,
public ?int $x = null,
public ?int $y = null,
public ?int $width = null,
public ?int $height = null,
public ?TemplateConfig $template = null,
public ?string $defaultValue = null, // checkbox: 'true'/'false'; date: a fixed MM/DD/YYYY (omit to auto-fill the signing date)
public bool $isMultiline = false,
public bool $isReadonly = false,
public bool $required = false,
public ?string $backgroundColor = null,
public ?FieldMetadata $metadata = null // Conditional (IF/THEN) metadata
) {}
}

// Conditional (IF/THEN) metadata
final class FieldMetadata {
public function __construct(
public ?string $fieldKey = null, // On a controlling checkbox
public ?FieldConditional $conditional = null // On a dependent field
) {}
}

final class FieldConditional {
public function __construct(
public string $controllingFieldKey, // = the checkbox's fieldKey (non-empty)
public ConditionalOperator $operator, // ConditionalOperator::IS_CHECKED | ::IS_NOT_CHECKED
public ConditionalAction $action // ConditionalAction::SHOW | ::UNLOCK
) {}
}

Request Objects​

final class SendSignatureRequest {
public function __construct(
public array $recipients, // Recipient[]
public array $fields, // Field[]
public ?string $file = null,
public ?string $fileName = null,
public ?string $fileLink = null,
public ?string $deliverableId = null,
public ?string $templateId = null,
public ?string $documentName = null,
public ?string $documentDescription = null,
public ?string $senderName = null,
public ?string $senderEmail = null,
public ?array $ccEmails = null
) {}
}
File Source (Conditional)

Exactly one file source is required: file, fileLink, deliverableId, or templateId.


Additional Documentation​

For detailed information about advanced configuration and API concepts, see:

Core API References​

  • Request Body Reference - Complete request body parameters, file sources, and multipart/form-data structure
  • Recipients Reference - Recipient properties, signing order, metadata, and configuration options
  • Field Types Reference - All available field types (signature, date, text, checkbox, etc.) with properties and behaviors
  • Field Positioning Methods - Template-based vs coordinate-based positioning, anchor configuration, and best practices

Resources​