Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Yousign Api Client Laravel Package

yousign/yousign-api-client

A PHP client for the YouSign electronic signature API that simplifies creating, sending, and managing signature requests, documents, and workflows from Laravel or plain PHP applications with a clean, fluent interface.

View on GitHub
Deep Wiki
Context7

Getting Started

composer require yousign/yousign-api-client

Add credentials to .env — sandbox first, never production on day one:

YOUSIGN_API_KEY=...
YOUSIGN_BASE_URL=https://api-sandbox.yousign.app/v3

Wire it into config/services.php so nothing hardcodes URLs:

'yousign' => [
    'api_key'  => env('YOUSIGN_API_KEY'),
    'base_url' => env('YOUSIGN_BASE_URL', 'https://api-sandbox.yousign.app/v3'),
],

The client is generated from Yousign's v3 OpenAPI spec, so the shape you get is: a Configuration object (host + bearer key), then one API class per resource (SignatureRequestApi, DocumentApi, SignerApi, …), plus model/DTO classes for request bodies. Confirm the exact namespaces against vendor/yousign/yousign-api-client/src before writing your first class — the generated code is the real documentation.

Register it once in a service provider and never new it in a controller:

$this->app->singleton(\Yousign\Client\Configuration::class, fn () => \Yousign\Client\Configuration::getDefaultConfiguration()
    ->setHost(config('services.yousign.base_url'))
    ->setApiKey('bearerAuth', config('services.yousign.api_key')));

First use case: a signature request for a single PDF. The v3 flow is always the same four calls — create the signature request (draft), upload a document, add a signer, then activate it. Nothing is sent to anyone until activation. Build a throwaway artisan command or tinker session that walks those four steps against sandbox, prints the activation response, and you'll understand 80% of the package.

Implementation Patterns

Wrap it, don't sprinkle it. Put the generated client behind your own App\Services\Yousign\YousignGateway interface with intent-named methods (requestSignature(), cancel(), downloadSignedDocument()). Reasons: the generated classes are verbose, they change on spec bumps, and an interface lets you fake the whole thing in tests without hitting the network.

Model the state machine locally. Yousign signature requests move draft → ongoing → done | declined | expired | canceled. Keep a signature_requests table with yousign_id, status, and your own domain status. Treat Yousign as the source of truth but store enough locally to render a UI without an API call per page load.

Prefer webhooks over polling. Configure the webhook URL in the Yousign dashboard, then in a controller:

Route::post('/webhooks/yousign', YousignWebhookController::class)
    ->withoutMiddleware(['csrf']);

Verify the signature header against your webhook secret, return 200 fast, and dispatch a job that re-fetches the signature request by ID before mutating anything. Re-fetching is the important bit — it keeps your DB in sync even if a webhook is missed or you replay an old one.

Queue the writes. Document uploads and activations are network-bound and can take seconds. CreateSignatureRequestJob, ActivateSignatureRequestJob — retry 3 times with backoff, and make each job idempotent by checking local state before calling Yousign.

Documents come from storage, not the request body. If a user just uploaded a PDF, keep it on disk (or S3) and have the job read it there. Streaming large files through a queued payload is how you get 20 MB jobs serialized into the queue table.

Config-driven signature level. electronic_signature (simple), advanced_electronic_signature, qualified_electronic_signature are per-signer settings with different legal weight and cost. Put the default in config, let business rules override it per document type.

Sandbox and production in parallel. Because the base URL lives in config, you can run a yousign:sync command against sandbox in CI and against production in a scheduled job without code forks. Just make sure the API keys are scoped to a single environment — they are not interchangeable.

Gotchas and Tips

  • The key goes in the Authorization header, and the SDK expects the raw key — don't prefix it with Bearer yourself if setApiKey does it for you. Double-prefixing yields a 401 that looks like a bad key.
  • Generated client error surface is uniform. Everything non-2xx throws the same exception class carrying getCode() (HTTP status) and a decoded body. Check 422 (validation — read the body, it names the bad field), 429 (throttle — back off, don't retry immediately), and 401 (key or wrong base URL; sandbox keys against the prod host fail here).
  • Webhooks are not signed unless you enable the secret. Without verification anyone can POST a fake done. Verify, and also re-fetch by ID as described above — belt and braces.
  • Timestamps are ISO 8601 UTC. Cast on the way in and store as UTC in Eloquent; European users expect local time on the way out.
  • Pagination is cursor-based (after + limit in v3), not page numbers. Loops written as for ($page = 1; ...) won't terminate the way you expect — walk the cursor until it comes back empty.
  • Activation is a one-way door. Once a signature request is ongoing you cannot edit documents or signers — you cancel and start over. Validate everything (signer email, phone, signature level, document ordering) before the activate call, ideally with a dry-run path.
  • Ordering of signers matters. signer_order / sequential mode is a property of the signature request, not per signer. Get it wrong and the second signer is blocked forever waiting on a step you didn't configure.
  • Sandbox does not send real emails. Don't burn an afternoon debugging deliverability. Use the signing link returned on the signer/signature request payloads to open the flow yourself.
  • PDF constraints are strict: max page count, max file size (~25 MB in v3), PDF only. Reject bad uploads at the form-validation layer with your own message rather than surfacing Yousign's 422 to the user.
  • Don't composer update the client in isolation. Regenerating from a new spec can rename models or change constructor signatures — it's a breaking change disguised as a patch bump. Pin it, diff src/ on upgrade.
  • Testing: Http::fake() won't intercept this client if it has its own Guzzle instance. Fake at your YousignGateway interface boundary, and keep a single opt-in integration test that runs against sandbox in CI with a YOUSIGN_SANDBOX_KEY secret.
  • Store the Yousign document ID, not the PDF. The signed PDF is downloadable via DocumentApi and its hash is what you want in an audit trail. Storage bills and stale-file bugs both come from mirroring files you don't need.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle