Adobe Sign PHP SDKconceptlz/adobe-sign GitHub

PHP 8.2+ · Acrobat Sign REST API v6

Contracts, signed from PHP.

conceptlz/adobe-sign uploads your documents, sends them for signature in any order, lets each project choose the legal signature level it needs (SES, AES or QES), reports progress through webhooks and hands you the signed PDF. It runs in any PHP project and uses only PSR interfaces.

composer require conceptlz/adobe-sign

What it does

Adobe Acrobat Sign is Adobe's e-signature service. Its REST API is large (agreements, documents, participants, events, webhooks, users, web forms, bulk sends) and has some details that are easy to get wrong in production: the account lives in a specific data centre, writes need the latest ETag, rate limits come with a Retry-After, and some responses differ from the published spec. This SDK handles those details, so the code you write reads like the business process:

send-contract.php
use Conceptlz\AdobeSign\AdobeSign;
use Conceptlz\AdobeSign\Builder\{AgreementInfo, FileInfo, ParticipantSetInfo, WebhookInfo};
use Conceptlz\AdobeSign\Webhook\EventType;

$sign = AdobeSign::withIntegrationKey(getenv('ADOBE_SIGN_INTEGRATION_KEY'));

// 1. Upload the PDF
$documentId = $sign->transientDocuments()->upload('/path/to/contract.pdf');

// 2. Create the agreement with a signing order, and send it
$agreementId = $sign->agreements()->create(
    AgreementInfo::create('Master Services Agreement')
        ->file(FileInfo::transientDocument($documentId))
        ->participantSet(ParticipantSetInfo::signer('client@example.com')->order(1))
        ->participantSet(ParticipantSetInfo::approver('legal@example.com')->order(2)) // order 2: these two
        ->participantSet(ParticipantSetInfo::signer('cfo@example.com')->order(2))     // act in parallel
        ->participantSet(ParticipantSetInfo::signer('ceo@example.com')->order(3))
        ->message('Please review and sign.'),
);

// 3. Get notified as people sign
$sign->webhooks()->create(
    WebhookInfo::forAgreement('Contract sync', 'https://app.example.com/adobe-sign/webhook', $agreementId)
        ->events(EventType::AGREEMENT_ALL),
);

// 4. Once everyone has signed: download the signed PDF and save it
if ($sign->agreements()->get($agreementId)->isSigned()) {
    $pdf = $sign->agreements()->combinedDocument($agreementId, attachAuditReport: true);
    file_put_contents("storage/agreements/$agreementId.pdf", $pdf->detach());
}

Features

  • Both auth methodsIntegration Key for your own account, or OAuth 2.0 so users connect their own Acrobat Sign accounts. Tokens refresh automatically, and asUser() acts on behalf of another user in the account.
  • Signing orderSequential, parallel or mixed ("client first, then CFO and legal together, then CEO") with a single order() call per participant.
  • Signature levelsSES by default, and AES or QES per project or per signer. After signing, signatureEvidence() shows what each signer actually reached.
  • Identity checksEmail one-time code, SMS, WhatsApp, password, knowledge-based questions, government ID or national eID, set with one verifyWith() call.
  • WebhooksHandles Adobe's verification handshake and turns each notification into a typed event object.
  • Production plumbingData-centre discovery with caching, retries that honour Retry-After, automatic If-Match, generators for paginated lists, streams for uploads and downloads.
  • Typed errorsOne exception per failure kind (authentication, not found, validation, rate limit, stale ETag, account capability, transport), with credentials always redacted.
  • Spec-checked313 models generated from Adobe's OpenAPI spec. Every request and response in the test suite is validated against it, and the SDK has been tested against a real account.

How the pieces fit

Your code talks to one object, AdobeSign. It hands out resource groups (agreements(), transientDocuments(), webhooks(), …). Every call goes through the same pipeline before it reaches Adobe:

Your code builders, models AdobeSign agreements() webhooks() … Transport TokenProvider RetryMiddleware EtagMiddleware PSR-18 client Acrobat Sign api.na4.adobesign.com GET /baseUris (cached)
Each request picks up a token, retries on rate limits, sends If-Match when needed, and goes to the data centre your account lives in, which the SDK discovers once and caches.

Two packages, one release

PackageUse it whenDepends on
conceptlz/adobe-signAny PHP project: Symfony, Slim, WordPress plugins, CLI tools, queues.PSR-18/17/7, PSR-16, PSR-3, PSR-20, php-http/discovery
conceptlz/adobe-sign-laravelLaravel 12 or 13: adds config, a facade, OAuth routes, a token table and a webhook route.this package + illuminate/*

Both packages share one version number and are always released together.

Where next