Skip to main content

Electronic invoicing mandates

The mandate is the document by which a company authorizes Scribee, as a Plateforme Agréée (French approved e-invoicing platform), to act on its behalf in the e-invoicing reform: issuing its invoices, receiving them, transmitting its e-reporting. It is the onboarding gate for every client you bring on: without an Active mandate, the company cannot be registered in the national directory or receive its invoices through Scribee. This page walks through the entire journey, to be replayed for each company: creation, signature (two paths), KYC documents, submission for review, activation - then termination and deletion.

What Scribee does for you​

  • Determines the mandate type (kind): delegation when your workspace is an accounting firm or a tax representative, standard otherwise. You never send it in the request.
  • Assigns the mandate number (mandate_number) from the SIREN of the company record.
  • For the electronic signature, generates the regulatory mandate document (PDF, in French) from the declared company record and signer, sends it by email to the signer, then attaches the signed document to the mandate with no action on your part.
  • When that electronic signature completes, submits the mandate for review with no call on your part, provided it already meets the other submission conditions (step 4).
  • Creates, as soon as the mandate is created, the three KYC document requests for a standard mandate: Kbis extract, identity document, proof of signing capacity (KYC documents).
  • Refuses, with a 422, a mandate whose scope overlaps that of another mandate of the same company - at creation, on modification when a scope is added or when the date window widens, and on resubmission of a Rejected mandate (see The three scopes).
  • On approval of a mandate covering receive_invoices, triggers the company's registration in the national directory (The national directory).
  • Terminates the mandate on the scheduled date, through a daily sweep that runs at 00:15 UTC - that is 01:15 in Paris in winter time and 02:15 in summer time. You call nothing on the day itself.

The three scopes​

A mandate carries 1 to 3 scopes (scopes), each at most once:

scopeLabelWhat the mandate authorizes
receive_invoicesReceive invoicesReceiving its e-invoices - a prerequisite for registration in the national directory
send_invoicesSend invoicesIssuing its e-invoices
e_reportingE-reportingThe e-reporting of its transactions

The same scope can be covered by only one of the company's mandates over overlapping dates, counting all of its mandates except the Rejected, Terminated and Deleted ones. A creation that would produce a duplicate responds 422. A Rejected mandate therefore does not block the replacement mandate you create on the same scope and dates.

This check does not run on every save. It runs at creation, on a modification that adds a scope, on a modification that widens the date window: start_date moved earlier, end_date moved later or cleared - clearing it opens the window to infinity - and on POST /api/v1/mandates/{id}/submit_for_review from Rejected, since the resubmitted mandate covers its scopes again. In the modification cases, a PATCH that would make two mandates carrying the same scope overlap is refused with a 422, exactly as at creation (the dates being signed terms, such a PATCH presupposes an unlocked mandate anyway - see The lifecycle). A PATCH that only shrinks the window - start_date moved later, end_date moved earlier - or that resends the scopes list unchanged is not checked: a shrink cannot create an overlap the window did not already carry, and that exemption keeps a scheduled termination possible on a company that carries a legacy overlap.

The lifecycle: two independent tracks​

The mandate carries two distinct tracks, and they advance independently: the mandate state (state) tracks the administrative journey, the signature status (signature_status) tracks the signing of the document. Sending the mandate for electronic signature does not change its state - it stays Incomplete - and review does not change the signature status. A single automatic link connects them: when the electronic signature completes on a mandate that is otherwise complete, Scribee submits it for review itself (see Path A).

That independence stops at the terms the document carries: the signature locks them. As long as signature_status is pending or signed, a PATCH that changes any of the nine signed terms - scopes, start_date, end_date, previous_approved_platform_name, previous_approved_platform_siren, previous_approved_platform_matricule, signer_first_name, signer_last_name, signer_role - is refused with a 422 carrying code: "operation_failed", and details names each offending term. The mandate does not move: the refusal is total, never partial.

Two details that matter for integration: signer_email is never locked - it does not appear in the signed document - and resending a locked term with its current value is accepted. Only an actual change is refused, which lets you replay a full PATCH without splitting it up.

To really change those terms, lift the lock first: cancel the pending signature request (POST /api/v1/mandates/{id}/cancel_signature) or remove the signed document (DELETE /api/v1/mandates/{id}/signed_document), then edit, then obtain a new signature (see Undoing step 2).

The mandate state:

The signature status:

signature_statusLabelMeaning
not_initiatedNot initiatedNo signature request yet; both paths of step 2 remain open
pendingPendingElectronic signature request in progress with the signer; manual upload responds 422
signedSignedThe signed document is attached to the mandate (has_signed_document becomes true)
refusedRefusedThe signer declined or the request expired; start a new signature
cancelledCancelledThe pending signature request was cancelled through POST /api/v1/mandates/{id}/cancel_signature (or from the Scribee interface), or by a trigger_signature that cancelled the pending request without completing; the mandate is modifiable and signable again, exactly like not_initiated

pending and signed are the two statuses that lock the mandate's terms; not_initiated, refused, and cancelled leave it modifiable. Two endpoints lift the lock: POST /api/v1/mandates/{id}/cancel_signature cancels a Pending request and moves the status to cancelled, and DELETE /api/v1/mandates/{id}/signed_document removes a signed document and brings the status back to not_initiated - never to cancelled.

Step 1: create the mandate​

This call creates the mandate in the Incomplete state in your workspace; nothing is transmitted externally, and the mandate stays deletable as long as it is not Active. The company is a record in your workspace (Companies and establishments). The write OAuth scope is required.

curl -X POST https://app.scribee.tech/api/v1/companies/YOUR_COMPANY_ID/mandates \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"mandate": {
"start_date": "2026-09-01",
"signer_first_name": "Jean",
"signer_last_name": "Dupont",
"signer_role": "Dirigeant",
"signer_email": "jean.dupont@exemple.fr",
"scopes": ["receive_invoices", "send_invoices", "e_reporting"]
}
}'

Response 201, abbreviated to the fields useful here:

{
"data": {
"id": 42,
"company_id": 7,
"scopes": ["e_reporting", "receive_invoices", "send_invoices"],
"kind": "standard",
"state": "incomplete",
"mandate_number": "123456789_01",
"start_date": "2026-09-01",
"end_date": null,
"signer_email": "jean.dupont@exemple.fr",
"has_signed_document": false,
"kyc_required": true,
"signature_status": "not_initiated"
}
}

start_date (the effective date), signer_first_name, signer_last_name, signer_role, and scopes are required. signer_email is required at creation when your workspace is an accounting firm or a tax representative (the mandate created is then of type delegation); for a standard mandate, it can be supplied later, but the electronic signature requires it. end_date is optional and cannot precede start_date (an end_date equal to start_date is accepted).

If the company is leaving another Plateforme Agréée for Scribee, provide previous_approved_platform_name, along with either previous_approved_platform_siren (French operator, 9 digits) or previous_approved_platform_matricule (foreign operator without a SIREN).

As long as the mandate is Incomplete or Rejected, it can be modified via PATCH /api/v1/mandates/42 with the same fields; a scopes array sent on modification replaces the mandate's entire set of scopes. The mandate state says whether it is modifiable; the signature status says what still is: as soon as a signature is Pending or completed, the nine terms the signed document carries are locked (see The lifecycle).

Step 2: obtain the signature - two paths​

Both paths lead to the Signed status, a condition for submission for review. Each one can be undone from the API, but only one path advances at a time:

  • As long as an electronic request is Pending, manual upload responds 422: cancel the request first (POST /api/v1/mandates/{id}/cancel_signature).
  • As long as a signed document is attached, path B responds 422, and as long as signature_status is signed, trigger_signature responds 422 too. Removing the signed document (DELETE /api/v1/mandates/{id}/signed_document) reopens both paths.
  • A second trigger_signature while a request is Pending first cancels that request with the provider, then creates a new request and sends a new email to the signer. Each call opens a new request: to restart a Pending signature, a new call is enough, with no prior cancellation.
  • If that cancellation fails, Scribee reads the request's state at the provider. Already signed: the call responds 422 with code: "operation_failed", with no new request, and the signature is recorded when the provider's signature event arrives, as in path A. Already ended (cancelled, expired, or declined): the new request replaces it. In any other case - request still in progress, or state unreadable -, the call responds 422 with code: "validation_failed": no new request is created, and the first one stays recorded, Pending.
  • If the mandate's signature request changes at the same moment - for example another trigger_signature or a cancel_signature in progress -, the call responds 422 with code: "operation_failed": re-read the mandate, then retry. If the mandate's terms are modified while trigger_signature prepares the request - possible on a mandate with no Pending request, and on a second call as soon as the Pending request is cancelled -, the call responds 422 with code: "operation_failed" and Scribee asks the provider to withdraw the new request: re-read the mandate, then call trigger_signature again. If the new request cannot be created once the first one is cancelled, the call fails and signature_status is cancelled: trigger_signature can be called again.
  • trigger_signature on an Incomplete mandate that is already Signed is refused with a 422 carrying code: "operation_failed": a completed signature is never silently replaced, nor its document overwritten. Remove the signed document, then trigger again.

Path A: electronic signature​

This call creates an electronic signature request and sends a real email to the signer, containing the signature link with verification by a one-time code received by email. There is no test environment: the address provided receives this email in production. The request expires after 14 days; its exact deadline is read from signature_provider_expires_at. The mandate must be Incomplete; its state does not change, only the signature status moves to Pending.

curl -X POST https://app.scribee.tech/api/v1/mandates/42/trigger_signature \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"signer_email": "jean.dupont@exemple.fr", "locale": "fr"}'

signer_email is optional: if omitted, the call uses the address already carried by the mandate. locale (fr or en, fr by default) sets the language of the signing interface; the mandate document itself is in French, being a regulatory document.

Triggers are limited per mandate, per workspace, per OAuth application and per signer address; beyond a limit, the call responds 429 without sending anything (see Errors and edge cases).

Then track the request - a read with no side effect, the read scope is enough:

curl https://app.scribee.tech/api/v1/mandates/42/signature_status \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
{
"data": {
"id": 42,
"state": "incomplete",
"signature_status": "pending",
"signature_provider_status": "ongoing",
"signature_provider_expires_at": "2026-09-15T09:30:00+02:00"
}
}

Timestamps are rendered in the Europe/Paris time zone, with the explicit offset (+02:00 in summer time, +01:00 in winter) - never a Z.

signature_provider_status is ongoing, done, declined, or expired, and null as long as no request has been created. Upon signing, Scribee downloads the signed document and attaches it to the mandate with no action on your part: signature_status moves to signed and has_signed_document to true. If the mandate then already meets the other conditions of step 4 - the three standard KYC documents provided when kyc_required is true, no requested document in the requested or rejected status - Scribee submits it for review within moments: state moves to pending_review with no submit_for_review call on your part. Between the signature and that submission, the mandate can briefly read with signature_status at signed and state still at incomplete. Otherwise the mandate stays Incomplete with signature_status at signed, and you submit it yourself in step 4 once the missing item is provided. Uploading the KYC documents before triggering the signature therefore lets the mandate go to review as soon as it is signed. If the signer declines or the request expires, signature_status moves to refused - then trigger trigger_signature again.

Path B: upload a signed document​

This call attaches a signed PDF to the mandate and moves the signature status to Signed; nothing is transmitted externally. It serves the circuit where the document is signed outside Scribee - handwritten signature or your own tool. The mandate must be Incomplete or Rejected, the file is a PDF of 50 MB maximum, and no signed document must already be attached. The API exposes the removal of an attached document, but never its download: as long as a document is in place, path B is closed for that mandate, and the only signal exposed is the has_signed_document boolean. The PDF you uploaded is never retrievable through the API, including after its removal - keep your own copy. To replace it, remove it then upload the new one; to obtain a copy, contact Scribee.

curl -X POST https://app.scribee.tech/api/v1/mandates/42/upload_document \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-F "file=@mandat_signe.pdf"

Response 200: the mandate with signature_status at signed and has_signed_document at true. state does not change: unlike path A, the upload never submits the mandate for review - submit it in step 4.

Undoing step 2: cancel a request or remove a signed document​

Two endpoints undo step 2 and lift the lock on the mandate's terms. Both respond 200 with the updated mandate.

Cancel a Pending request. The write scope is required. The signature request in progress is cancelled with the provider, signature_status moves to cancelled, and signature_provider_status and signature_provider_expires_at come back to null. Scribee no longer records a signature from that request. The mandate becomes modifiable again and both paths reopen. A mandate whose signature_status is not pending responds 422. If the mandate's signature request changes during the call - a trigger_signature or another cancel_signature in progress -, the call responds 422 with code: "operation_failed": re-read the mandate, then retry.

curl -X POST https://app.scribee.tech/api/v1/mandates/42/cancel_signature \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Remove a signed document. Either the write or the destroy scope is enough. The PDF is detached, signature_status comes back to not_initiated, and has_signed_document to false. The mandate must be Incomplete or Rejected and must carry a signed document; otherwise, 422. The mandate is then no longer submittable until a new signature completes, through either path.

curl -X DELETE https://app.scribee.tech/api/v1/mandates/42/signed_document \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Step 3: provide the KYC documents​

The mandate's kyc_required field tells you whether this step applies. It is false when your workspace is an accounting firm or a tax representative - the same workspaces for which the mandate created is of type delegation - and true everywhere else. When it is true, Scribee has already created the three requests when the mandate was created: all that remains is for you to upload the files.

Scribee can also request an additional document during review (kind: additional); it appears in the same list and blocks submission until it is provided, including when kyc_required is false.

curl https://app.scribee.tech/api/v1/mandates/42/kyc_documents \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Abbreviated response:

{
"data": [
{ "id": 103, "kind": "signing_capacity_proof", "status": "requested", "has_file": false },
{ "id": 102, "kind": "identity_paper", "status": "requested", "has_file": false },
{ "id": 101, "kind": "kbis_extract", "status": "requested", "has_file": false }
]
}

The list is sorted by created_at descending by default, so the three standard requests come back in the reverse of their creation order.

Uploading the files, each document's statuses, and their rules are detailed in KYC documents.

Step 4: submit the mandate for review​

This call moves the mandate to Pending review; the review is carried out by the Scribee team, nothing is transmitted externally. Five conditions, checked in this order: the mandate is Incomplete or Rejected; signature_status is signed (either path of step 2); the three standard KYC documents are provided, when kyc_required is true; no requested document is left in the requested or rejected status; for a resubmission from Rejected, no Incomplete, Pending review or Active mandate of the company covers one of its scopes over overlapping dates. Otherwise the call responds 422 and the mandate stays in its state.

After a signature through path A, re-read state first: if the mandate already met these conditions at signing, Scribee submits it itself within moments and it moves to Pending review. A mandate still Incomplete right after the signature may therefore still be submitted automatically: re-read state before submitting it yourself. submit_for_review on a mandate already submitted responds 422, since it is no longer Incomplete (see Errors and edge cases): go straight to step 5. After path B, the call is always required.

curl -X POST https://app.scribee.tech/api/v1/mandates/42/submit_for_review \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Abbreviated response:

{
"data": {
"id": 42,
"state": "pending_review",
"signature_status": "signed"
}
}

Step 5: track the review through to activation​

The review concludes with no call on your part; re-read the mandate to observe the outcome - the read scope is enough.

curl https://app.scribee.tech/api/v1/mandates/42 \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Three possible outcomes:

  • state moves to active: the mandate is in force as soon as its contractual period covers the current day - the formal agreement carries the date from which Scribee may act on the company's behalf. In the API, it is that combination - the active state and a period under way - that unlocks national directory writes for that company (The national directory); no other endpoint has an active-mandate precondition. The two bounds do not work the same way: start_date counts the day itself, so a mandate starting today already opens those writes whereas a mandate starting tomorrow does not open them yet; end_date, on the other hand, does not count the day itself, so a mandate whose end_date falls today already refuses them: the period's last day does not count.
  • state moves to rejected: the mandate becomes modifiable again. The rejection reason is viewable in the Scribee interface. Rejection touches only state: the signature status and the signed document are kept, so the lock is kept too - as long as the signed document is attached, a PATCH on any of the nine signed terms responds 422. If only the KYC documents are at fault, submit again directly, carrying the original signature. If the terms are, the correction loop is: DELETE /api/v1/mandates/{id}/signed_document, then PATCH /api/v1/mandates/{id}, then a new signature, then POST /api/v1/mandates/{id}/submit_for_review. From Rejected, that new signature goes through path B: trigger_signature only runs from Incomplete. A Rejected mandate does not block a replacement mandate on the same scope; but once that replacement is created, resubmitting the Rejected mandate responds 422 (see The three scopes).
  • state returns to incomplete: Scribee requests changes or an additional document - re-read the KYC list from step 3, then submit again.

All of a company's mandates are listed via GET /api/v1/companies/YOUR_COMPANY_ID/mandates (sorted by state, mandate_number, start_date, or created_at, defaulting to created_at descending; associations company and kyc_documents via include).

Terminate an active mandate​

This call schedules the termination: the mandate stays Active with end_date set, and the daily 00:15 UTC sweep (01:15 or 02:15 in Paris depending on the season) moves it to Terminated once the date is reached. Nothing is transmitted externally by this call. end_date must be at the earliest tomorrow (J+1); until the effective date, the termination is cancelled by calling the same endpoint again without end_date (or with null).

The scheduled date is not the only route into Terminated: Scribee can also terminate an Active mandate immediately from its internal interface, with no end_date. A mandate you re-read may therefore have moved to Terminated while its end_date is null.

curl -X POST https://app.scribee.tech/api/v1/mandates/42/terminate \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"end_date": "2026-12-31"}'

Abbreviated response:

{
"data": {
"id": 42,
"state": "active",
"end_date": "2026-12-31",
"termination_date": null
}
}

Once terminated, the mandate carries termination_date and the Terminated state is final: to reauthorize Scribee, create a new mandate.

Delete a mandate​

DELETE removes a mandate that will never be activated - a data-entry error, an abandoned journey. Allowed from Incomplete, Pending review, and Rejected; an Active or Terminated mandate responds 422. The write scope is required.

curl -X DELETE https://app.scribee.tech/api/v1/mandates/42 \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response 204, with no body. The deletion is logical: the mandate moves to the Deleted state, remains readable in lists and individually, and is no longer modifiable or submittable. A second DELETE on that mandate responds 422 with the same message as on an Active or Terminated mandate - a message that nonetheless names only those two states.

If the signature request is Pending (signature_status is pending), Scribee also withdraws it with the provider, in the background and on a best-effort basis, with no guarantee of success: once withdrawn, the link already sent to the signer no longer leads anywhere, while the deleted mandate keeps signature_status at pending. If the signer had already signed before that withdrawal took effect, Scribee still attaches the signed document to the deleted mandate, as proof: has_signed_document becomes true, with no other effect on the mandate - state stays at deleted, signature_status at pending, the mandate is not submitted for review, and that document cannot be removed (422).

What happens next​

  • On approval of a mandate covering receive_invoices, Scribee triggers the company's registration in the reform's national directory, kept by the PPF (Portail Public de Facturation) - with no call on your part: The national directory.
  • An Active mandate whose contractual period covers the current day is the prerequisite for the company's directory entries: without it, they respond 403.
  • Once the mandate is Active, proceed with the business integration: Issue a sales invoice, Receive supplier invoices, Declare transactions.

Errors and edge cases​

Validation failures respond 422 with error: "unprocessable_entity", code: "validation_failed", and the cause in details.base. Several refusals on this page carry code: "operation_failed" and a different shape (see below). Base your handling on the HTTP status and on code, never on the message text (API conventions).

{
"error": "unprocessable_entity",
"code": "validation_failed",
"message": "La validation a échoué",
"details": {
"base": ["Le mandat doit être en état incomplet pour initier la signature"]
}
}

The causes by message, in the same format. The table is not exhaustive: any other model validation comes back in details.base, in the same format.

details.baseCauseWhat you do
Périmètres doit comporter au moins 1 périmètre.scopes empty or missing at creationprovide 1 to 3 scopes from the table
Périmètres n'est pas validea scopes value is not in the scope tablesend only receive_invoices, send_invoices, or e_reporting; the message does not name the offending value
Périmètres Un mandat actif couvre déjà l'un des périmètres sélectionnés.another mandate of the company, neither Rejected, nor Terminated, nor Deleted, already covers this scope over overlapping dates - at creation, on modification, or on resubmission of a Rejected mandatereuse the existing mandate, or terminate it first; on resubmission, carry on with the mandate that already covers the scope
Le mandat doit être en état incomplet ou rejetéPATCH, upload_document, or submit_for_review on a non-modifiable mandate, including a mandate already submitted automatically when its electronic signature completedre-read state; only Incomplete and Rejected are modifiable, and a mandate already pending_review no longer needs submitting
Le mandat doit être en état incomplet pour initier la signaturetrigger_signature outside the Incomplete stateonly an Incomplete mandate goes out for electronic signature; from Rejected, use path B
L'adresse e-mail du signataire est requise pour initier la signatureno signer_email, neither in the call nor on the mandateprovide signer_email
Annulez la demande de signature en cours avant de télécharger un document manuel.upload_document during an electronic request that is Pendingcancel the request (POST /api/v1/mandates/{id}/cancel_signature), or wait for its outcome
Un document signé est déjà associé. Retirez-le avant d'en téléverser un nouveau.upload_document on a mandate that already carries a signed documentremove the document in place (DELETE /api/v1/mandates/{id}/signed_document) before uploading the new one
La demande de signature ne peut être annulée que tant qu'elle est en attentecancel_signature on a mandate whose signature_status is not pendingre-read signature_status; a completed signature is undone by removing the signed document
Erreur du fournisseur de signature : ...trigger_signature or cancel_signature: the electronic signature provider could not process the request (temporarily unavailable, or a refusal on its side); the text after the colon variescall the same endpoint again later; after a trigger_signature on a mandate with no Pending request, signature_status has not moved to pending and the mandate stays Incomplete; after a trigger_signature on a Pending request, re-read signature_status: pending if cancelling the first request failed, which then stays recorded, cancelled if the new request could not be created; after cancel_signature, signature_status is still pending and the mandate is unchanged
Le document signé ne peut être supprimé que sur un mandat modifiableDELETE .../signed_document outside the Incomplete and Rejected statesre-read state; an Active mandate's document cannot be removed
Aucun document signé n'est associé à ce mandatDELETE .../signed_document on a mandate with no attached documentnothing to remove; has_signed_document was already false
Un fichier est requisupload_document without a file fieldsend the PDF as multipart/form-data, field file
Document de mandat signé doit être un fichier PDFfile of another typeconvert to PDF
Document de mandat signé doit être inférieur à 50 Mofile too largecompress the PDF
La signature électronique du mandat est requise avant soumission.submit_for_review while signature_status is not signedcomplete step 2, whichever path
Tous les documents KYC requis doivent être téléchargés avant la soumissionone of the three standard KYC documents is missing, on a mandate whose kyc_required is truecomplete step 3
Tous les documents demandés doivent être téléchargés avant la soumission pour révisiona document requested by Scribee is still to be provided, or was rejectedre-read the KYC list and provide it
Le mandat doit être actifterminate on a non-Active mandateonly Active mandates can be terminated
La date de résiliation doit être au plus tôt demainend_date today or in the pastprovide a date at J+1 minimum
Date de résiliation invalideend_date in a non-ISO-8601 formatsend YYYY-MM-DD
Aucune résiliation planifiée à annulerterminate without end_date while no termination is schedulednothing to replay
Les mandats actifs et résiliés ne peuvent pas être supprimésDELETE on an Active, Terminated, or already Deleted mandateterminate an Active mandate (the terminate endpoint) instead of deleting it

422: the signature lock​

The two signature-lock refusals do not go through details.base. They carry code: "operation_failed", and their message is the cause itself. A PATCH on a locked term additionally names each offending term in details, one term per key:

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Les termes du mandat sont verrouillés tant que sa signature est en attente ou aboutie. Annulez la demande de signature en attente ou retirez le document signé, puis modifiez le mandat.",
"details": {
"signer_first_name": ["ne peut pas être modifié tant que la signature du mandat est en attente ou aboutie"]
}
}

trigger_signature on an already Signed mandate carries the same code, with no details:

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Le mandat est déjà signé. Retirez le document signé avant de déclencher une nouvelle signature."
}

The trigger_signature and cancel_signature refusals described in step 2 - a Pending request already signed at the provider, a signature request that changed in the meantime, mandate terms modified while the request was being prepared - carry this code too, with no details and the cause as message.

429: signature trigger limit​

trigger_signature is counted against several limits: per mandate; per workspace, by the minute and by the hour; per OAuth application, by the minute and by the hour, across all workspaces; and per signer email address within a workspace, with case and a +tag suffix ignored. The values are published in the API reference. Signatures triggered from the Scribee interface fall under the same per-mandate, per-workspace and per-signer-address limits. A 422 refusal for a mandate outside the Incomplete state, already Signed, or without a signer_email is not counted. Beyond a limit, the call responds 429 with a Retry-After header in seconds:

{
"error": "too_many_requests",
"code": "rate_limited",
"message": "Trop de requêtes. Veuillez réessayer plus tard."
}

Nothing was sent: no document was generated, the signature provider was not called, no email went out, and the mandate is unchanged. Wait Retry-After seconds, then retry. This value is an upper bound: it is the full length of the longest window exceeded, not the time remaining - each window opens at the first call it counts and can therefore close sooner.

403: insufficient scope​

Reads on this page require read. A token without the required scope - read for a read, write for a write, destroy or write for the two DELETE calls on this page (deleting the mandate and removing the signed document) - responds:

{
"error": "forbidden",
"message": "Vous n'êtes pas autorisé à effectuer cette action"
}

404 Not Found​

The company or the mandate does not exist, or belongs to a workspace outside your application's scope (Your first call):

{
"error": "not_found",
"message": "La ressource demandée est introuvable"
}

On these routes, a request issued from an IP address outside the workspace's allowlist gets the same 404, not a 403: the workspace becomes invisible rather than forbidden.

400 Bad Request: page beyond the last​

The mandate list and the KYC document list are paginated and respond 400 beyond the last page, as everywhere else: API conventions. One exception: when the collection is empty, there is no overflow. A company with no mandate, or a mandate with no KYC document, responds 200 with data: [] whatever page is requested.