API & Webhook Documentation
0. Authentication (login)
To use the API, first authenticate to obtain an access token (Bearer).
/api/login
Expected fields:
email
(string, required)password
(string, required)
Example request
POST /api/login Content-Type: application/json { "email": "admin@email.com", "password": "motdepasse" }
Example response
{ "token": "eyJ0eXAiOiJKV1QiLCJhbGciOi..." }
0.1. Registration (register)
To create a user account via the API.
/api/register
Expected fields:
name
(string, required) : Display nameemail
(string, required) : Email addresspassword
(string, required) : Passwordpassword_confirmation
(string, required) : Password confirmation
Example request
POST /api/register Content-Type: application/json { "name": "John Doe", "email": "john.doe@example.com", "password": "password123", "password_confirmation": "password123" }
Example response (success)
{ "status": "success", "message": "User created successfully.", "token": "eyJ0eXAiOiJKV1QiLCJhbGciOi..." }
Example response (error)
{ "status": "error", "message": "Validation error", "errors": { "email": ["The email address is already used."] } }
0.2. Generate a personal API token
To use the API, each user can generate one or more personal API tokens from their account area ("My API tokens" section). These tokens allow access to all protected API routes.
- Log in to your GesDocs account
- Go to "My Account" > "Manage my API tokens"
- Generate a new token and copy it (it will only be displayed once)
- Use this token in the header
Authorization: Bearer <token>
of your API requests
Example usage
POST /api/signature-requests Authorization: Bearer <your_api_token> Content-Type: multipart/form-data ...
0.3. Get available regions and languages
This endpoint returns the list of available regions (timezones) and languages for use in the API.
/api/meta
Example response
{ "regions": ["Europe/Paris", "Europe/London", ...], "languages": [ {"code": "fr", "label": "Français"}, {"code": "en", "label": "English"} ] }
1. Create a signature request (API)
Endpoint to create a remote signature request via the REST API.
/api/signature-requests
Accepted formats
- JSON : for sending only URLs (pdf_url, logo_url)
- multipart/form-data : for sending files (pdf, logo) and/or classic fields
Required fields
signers
(array, required): List of signers (email, first_name, last_name, language, ...)expires_at
(string, required): Expiration date (YYYY-MM-DDTHH:mm:ss)demandeur_email
(string, required): Requester emailpdf
(file, required in multipart) orpdf_url
(string, required in JSON)logo
(file, optional in multipart) orlogo_url
(string, optional in JSON)color
(string, optional): Main color (hex)metadata
(object, optional): Additional data
Example JSON request
POST /api/signature-requests Authorization: Bearer <token> Content-Type: application/json { "signers": [ { "email": "alice@email.com", "first_name": "Alice", "last_name": "Dupont", "language": "fr" } ], "expires_at": "2025-12-31T23:59", "demandeur_email": "admin@email.com", "pdf_url": "https://exemple.com/monfichier.pdf", "logo_url": "https://exemple.com/monlogo.png" }
Example multipart/form-data request
signers[0][email]
= alice@email.comsigners[0][first_name]
= Alicesigners[0][last_name]
= Dupontsigners[0][language]
= frexpires_at
= 2025-12-31T23:59demandeur_email
= admin@email.compdf
= (joindre le fichier PDF)logo
= (joindre le logo, optionnel)color
= #4f46e5 (optionnel)metadata
= {"custom_id": "ABC123"} (optionnel)
Notes
- If you use JSON, you must provide pdf_url (and optionally logo_url).
- If you use multipart, you must provide pdf (and optionally logo).
- If you provide both a file and a URL for the same field, the file is prioritized.
- Validation errors will indicate precisely missing or malformed fields.
Example response (success)
{ "status": "success", "message": "Signature request created successfully", "data": { "signature_request": { "id": 123, "email": "john.doe@email.com", "signer_first_name": "John", "signer_last_name": "Doe", "signer_language": "fr", "signer_2fa": true, "signer_mobile": "0612345678", "statut": "en_attente", "expires_at": "2025-12-31T23:59:00", "requester_email": "admin@email.com", "metadata": {"custom_id": "ABC123"}, "logo_url": "https://.../logos/xxxx.png", "color": "#4f46e5", "region": "Europe/Paris", ... }, "signature_url": "https://.../fr/sign/xxxx?email=...&check=...", "credits_left": 42 } }
The field credits_left
indicates the number of credits left for the authenticated user.
1.1. Mode multi-signataire et gestion des balises
GesDocs prend en charge le mode multi-signataire : vous pouvez définir plusieurs signataires pour un même document, chacun devant signer à des emplacements précis ou communs selon les balises présentes dans le PDF.
<@signature@>
: chaque signataire doit signer à cet emplacement (balise commune).<@signature1@>
,<@signature2@>
, etc. : seul le signataire n°N doit signer à cet emplacement (balise individuelle).- Si le document ne contient aucune balise, une page récapitulative est ajoutée à la fin du PDF signé, listant toutes les signatures (image, nom, prénom, date/heure).
Le webhook et l'API retournent pour chaque demande :
- La liste complète des signataires (
signataires
), avec leur statut et date de signature. - Le lien vers le PDF signé et le certificat PDF/JSON.
- Pour chaque événement, le webhook POSTe l'état de tous les signataires et le détail du document.
Exemple de payload Webhook pour un document multi-signataire :
{ "event": "document_signed", "data": { "id": 123, "token": "...", ... "signataires": [ { "email": "alice@email.com", "prenom": "Alice", "nom": "Dupont", "statut": "signed", "date_signature": "2025-05-04T15:00:00" }, { "email": "bob@email.com", "prenom": "Bob", "nom": "Martin", "statut": "pending", "date_signature": null } ], ... } }
Résumé : GesDocs gère nativement les workflows multi-signataires, l'API et le webhook exposent l'état de chaque signataire, et la page récapitulative PDF est générée automatiquement si aucune balise n'est présente dans le document.
2. Webhook (automatic notifications)
You can configure a webhook URL in the "My Account" section. For each event (signature, refusal, etc.), GesDocs will send a POST request with the event details.
Example JSON payload sent:
{ "event": "document_signed", "data": { "id": 123, "token": "a31e9ec7-b5a3-4b76-bf53-a35062ccff14", "document_hash": "...", "signataire": { "email": "alice@email.com", "prenom": "Alice", "nom": "Dupont" }, "signataires": [ { "email": "alice@email.com", "prenom": "Alice", "nom": "Dupont", "statut": "signed", "date_signature": "2025-05-04T15:00:00" }, { "email": "bob@email.com", "prenom": "Bob", "nom": "Martin", "statut": "pending", "date_signature": null } ], "statut": "signe", "date_creation": "2025-05-04T13:49:56", "date_expiration": "2025-05-04T14:49:00", "date_signature": "2025-05-04T15:00:00", "demandeur": { "email": "admin@email.com" }, "utilisateur": { "email": "admin@email.com", "entreprise": "Ma société" }, "document_signe": { "url": "https://.../pdf/signes/xxx.pdf" }, "certificat_pdf": { "url": "https://.../pdf/certificats/xxx.pdf" }, "certificat_json": { "url": "https://.../pdf/certificats/xxx.json" }, "ip": "1.2.3.4", "navigateur": "Mozilla/5.0 ...", "preuve": { ... }, "metadata": { ... } }, "credits_left": 42 }
The field credits_left
indicates the number of credits left for the user at the time of the event.
The webhook is called via POST, JSON format, for each important status change (signature, refusal, etc.).
2. Verify the authenticity of a signed document (API)
This endpoint allows you to verify the authenticity of a signed PDF document and its certificate PDF generated by GesDocs.
/api/verify-document
Expected fields (multipart/form-data)
document
(file, required) : The signed PDF document to verifycertificate
(file, required) : The certificate PDF generated by GesDocs
Example request (multipart/form-data)
POST /api/verify-document Authorization: Bearer <token> Content-Type: multipart/form-data document: <signed PDF file> certificate: <certificate PDF file>
Example response (success)
{ "valid": true, "message": "Signature valid and authentic.", "debug": { "hash_from_cert": "...", "hash_of_doc": "...", "uuid_from_cert": "...", "date_from_cert": "03/05/2025 20:01:09", "date_in_db": "03/05/2025 20:01:09" } }
Example response (failure)
{ "valid": false, "message": "The document hash does not match the certificate hash.", "debug": { "hash_from_cert": "...", "hash_of_doc": "...", "uuid_from_cert": "...", "date_from_cert": "03/05/2025 20:01:09", "date_in_db": "03/05/2025 20:01:09" } }
Secure Download (API)
This endpoint allows you to create a secure download link and notify recipients by email.
/api/secure-downloads
Expected fields (JSON or multipart/form-data)
files
(array of objects, required): List of files to share (path, name). You can provide a file path (uploaded) or a url (remote PDF).signers
(array of objects, required): List of recipients (email, first_name, last_name, language, region, mobile if 2FA SMS)demandeur_email
(string, required): Requester emailexpires_at
(date, required): Expiration date (YYYY-MM-DD)logo
(file, optional): Custom logo (image, shown in emails and download page)logo_url
(string, optional): URL of a custom logo image (PNG, JPG, GIF, WEBP). If both logo and logo_url are provided, the uploaded file is used.twofa_type
(string, optional): 2FA type (mail or sms, default: mail)
For each file in files[], you can provide either:
path
: Path to a file uploaded to S3 (from the web interface or presigned URL)url
: URL to a remote PDF file (the API will download and store it on S3)
If both path and url are provided, path is used.
Example request (JSON)
{ "files": [ { "name": "Document.pdf", "url": "https://example.com/file.pdf" }, { "name": "Autre.pdf", "path": "secure_downloads/abc123_Autre.pdf" } ], "signers": [ { "email": "john@example.com", "first_name": "John", "last_name": "Doe", "language": "en" } ], "demandeur_email": "alice@example.com", "expires_at": "2025-06-01T12:00:00", "logo_url": "https://example.com/logo.png" }
Example request (multipart/form-data)
files[0][name]: Document.pdf files[0][path]: secure_downloads/abc123_Document.pdf signers[0][email]: john@example.com signers[0][first_name]: John signers[0][last_name]: Doe demandeur_email: alice@example.com expires_at: 2025-06-01T12:00:00 logo: (file upload)
Example response (success)
{ "status": "success", "message": "Link sent to recipients.", "data": { "secure_download_id": 123, "token": "...", "expires_at": "2025-06-01T12:00:00", "link": "https://gesdocs.fr/secure-downloads/123" } }
Example response (error)
{ "status": "error", "message": "Unable to download the file from the provided URL.", "field": "files.0.url" } { "status": "error", "message": "The file at the provided URL is not a valid PDF.", "field": "files.0.url" } { "status": "error", "message": "Unable to download the logo from the provided URL.", "field": "logo_url" } { "status": "error", "message": "The file at the provided URL is not a valid image.", "field": "logo_url" }
If you provide a remote file or logo URL, the API will attempt to download and store it. If the file is not accessible or not valid, an error will be returned.