Μετάβαση στο κύριο περιεχόμενο
Certyneo
Δημόσιο API v1

Ενσωματώστε την ηλεκτρονική υπογραφή στο stack σας

Στείλτε φακέλους, παρακολουθήστε υπογραφές, λάβετε webhooks. Απλό REST API, OpenAPI 3.0, παραδείγματα curl/Node/Python — όλα όσα χρειάζεστε για να συνδέσετε τη Certyneo στο HRIS, CRM ή λογισμικό ενδοεπιχείρησής σας σε λίγες ώρες.

Γρήγορη έναρξη

Τρία βήματα: δημιουργήστε ένα API key από τις ρυθμίσεις, κωδικοποιήστε το PDF σας σε base64, στείλτε. Η απάντηση περιέχει το `signUrl` που μπορείτε να μοιράσετε απευθείας στον παραλήπτη.

cURLbash
# 1. Upload the PDF (multipart) and capture the returned document id.
DOC_ID=$(curl -s -X POST https://certyneo.com/api/v1/documents \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -F "file=@contrat.pdf" | jq -r .id)

# 2. Create a DRAFT envelope referencing the uploaded document.
ENV_ID=$(curl -s -X POST https://certyneo.com/api/v1/envelopes \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d "{
    \"subject\": \"Contrat de prestation\",
    \"documentIds\": [\"$DOC_ID\"],
    \"recipients\": [
      { \"email\": \"client@example.com\", \"name\": \"Marie Dubois\", \"role\": \"SIGNER\" }
    ]
  }" | jq -r .id)

# 3. Dispatch the envelope — this sends the invitation email/SMS.
curl -X POST https://certyneo.com/api/v1/envelopes/$ENV_ID/send \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx"
JavaScript / Nodets
// Plain fetch, no SDK to install.
const auth = { Authorization: `Bearer ${process.env.CERTYNEO_API_KEY}` };

// 1. Upload the PDF (multipart).
const fd = new FormData();
fd.append("file", new Blob([pdfBuffer], { type: "application/pdf" }), "contrat.pdf");
const doc = await fetch("https://certyneo.com/api/v1/documents", {
  method: "POST", headers: auth, body: fd,
}).then((r) => r.json());

// 2. Create the DRAFT envelope.
const envelope = await fetch("https://certyneo.com/api/v1/envelopes", {
  method: "POST",
  headers: { ...auth, "Content-Type": "application/json" },
  body: JSON.stringify({
    subject: "Contrat de prestation",
    documentIds: [doc.id],
    recipients: [
      { email: "client@example.com", name: "Marie Dubois", role: "SIGNER" },
    ],
  }),
}).then((r) => r.json());

// 3. Dispatch — this triggers the invitation channel for every recipient.
await fetch(`https://certyneo.com/api/v1/envelopes/${envelope.id}/send`, {
  method: "POST", headers: auth,
});
console.log(envelope.id);
Pythonpython
import os, requests

auth = {"Authorization": f"Bearer {os.environ['CERTYNEO_API_KEY']}"}

# 1. Upload the PDF (multipart).
with open("contrat.pdf", "rb") as f:
    doc = requests.post(
        "https://certyneo.com/api/v1/documents",
        headers=auth,
        files={"file": ("contrat.pdf", f, "application/pdf")},
    ).json()

# 2. Create the DRAFT envelope.
envelope = requests.post(
    "https://certyneo.com/api/v1/envelopes",
    headers={**auth, "Content-Type": "application/json"},
    json={
        "subject": "Contrat de prestation",
        "documentIds": [doc["id"]],
        "recipients": [
            {"email": "client@example.com", "name": "Marie Dubois", "role": "SIGNER"},
        ],
    },
).json()

# 3. Dispatch — this triggers the invitation channel for every recipient.
requests.post(
    f"https://certyneo.com/api/v1/envelopes/{envelope['id']}/send",
    headers=auth,
)
print(envelope["id"])

Δοκιμάστε το API από τα εργαλεία σας

Η συλλογή Postman και το φύλλο RapidAPI δημιουργούνται από την προδιαγραφή OpenAPI που τεκμηριώνει επίσης αυτή τη σελίδα. Οι τρεις παραμένουν λοιπόν ευθυγραμμισμένες με το πραγματικό API, ένα endpoint κάθε φορά, παρά να αποκλίνουν στην πρώτη προσθήκη.

Συλλογή Postman

Οι 25 αιτήματα ταξινομημένα κατά τομέα — φάκελοι, έγγραφα, πρότυπα, σφραγίδες, webhooks — με παράδειγμα σώματος και απάντησης για καθένα. Επικολλήστε το κλειδί σας στη μεταβλητή apiKey της συλλογής, στη συνέχεια εκτελέστε GET /health: δεν απαιτεί καμία πιστοποίηση και επιβεβαιώνει ότι η διαμόρφωσή σας είναι σωστή πριν από την πρώτη πιστοποιημένη κλήση.

Φύλλο RapidAPI

Ο ίδιος κατάλογος endpoints, δοκιμάσιμος απευθείας από το πρόγραμμα περιήγησης. Ο χώρος δοκιμών αναμένει δύο ξεχωριστές κεφαλίδες: το κλειδί RapidAPI που σας εκχωρεί η πλατφόρμα και το κλειδί Certyneo σας στο Authorization — το δεύτερο είναι αυτό που εξουσιοδοτεί πραγματικά την κλήση.

Φάκελοι

Δημιουργία, αποστολή, παρακολούθηση κατάστασης, ακύρωση. Ένας φάκελος μπορεί να περιέχει πολλά έγγραφα και πολλούς υπογράφοντες (παράλληλα ή διαδοχικά).

Δικτυακά δίκτυα

Όλα τα γεγονότα φακέλου και παραλήπτη (`envelope.sent`, `recipient.signed`, `envelope.completed`…) παραδοθείσαν στο URL της επιλογής σας — πλήρης λίστα στο /developers/webhooks. HMAC SHA-256 σε κάθε payload για επαλήθευση της προέλευσης.

Απλή αυθεντικοποίηση

Bearer token. Ένα κλειδί ανά περιβάλλον (test / prod). Ανακλητό αμέσως. Όριο 100 req/min/κλειδί, burst 200, 429 καθαρή με κεφαλίδα Retry-After.

Διαθέσιμα Endpoints

Οι 53 δημόσιες διαδρομές : λογαριασμός, έγγραφα, φάκελοι, πρότυπα, webhooks, ηλεκτρονικές σφραγίδες, κλειδιά API και τιμολόγηση. Όλες δέχονται ένα Bearer token και επιστρέφουν JSON.

ΜέθοδοςΔιαδρομήΠεριγραφή
GET/api/v1/account/meΤαυτότητα του επικυρωμένου καλούντος (id, e-mail, πακέτο) : δοκιμή αναγνωριστικών χωρίς απαιτούμενο scope
GET/api/v1/sandboxΚαταμέτρηση των δεδομένων που δημιουργήθηκαν με κλειδιά δοκιμής (διαγράφονται αυτόματα μετά από 30 ημέρες)
DELETE/api/v1/sandboxΔιαγραφή όλων των δεδομένων που δημιουργήθηκαν με κλειδιά δοκιμής, χωρίς να επηρεαστούν τα πραγματικά δεδομένα
POST/api/v1/documentsΜεταφόρτωση PDF (multipart) : επιστρέφει το id του εγγράφου
GET/api/v1/documentsΛίστα εγγράφων
GET/api/v1/documents/{id}Ανάγνωση μεταδεδομένων ενός εγγράφου
DELETE/api/v1/documents/{id}Διαγραφή ενός εγγράφου
GET/api/v1/envelopesΛίστα φακέλων (φίλτρο με ?status= και ?limit=)
POST/api/v1/envelopesΔημιουργία φακέλου (κατάσταση DRAFT) : από ένα templateId, ή από documentIds με ένα προαιρετικό πίνακα fields
GET/api/v1/envelopes/{id}Ανάγνωση κατάστασης ενός φακέλου
PATCH/api/v1/envelopes/{id}Τροποποίηση ενός φακέλου DRAFT
DELETE/api/v1/envelopes/{id}Διαγραφή ενός φακέλου DRAFT (409 μόλις αποσταλεί : ακυρώστε το αντί αυτού)
POST/api/v1/envelopes/{id}/sendΑποστολή ενός φακέλου DRAFT : στέλνει τις προσκλήσεις
POST/api/v1/envelopes/{id}/voidΑκύρωση ενός αποσταλμένου φακέλου που δεν έχει ακόμη υπογραφεί πλήρως : οι εκκρεμείς υπογράφοντες ειδοποιούνται
POST/api/v1/envelopes/{id}/remindΥπενθύμιση στους υπογράφοντες κατ' αίτημα που περιμένουν ένα αποσταλμένο φάκελο (προαιρετικά ένας συγκεκριμένος παραλήπτης)
GET/api/v1/envelopes/{id}/audit-trailΛήψη του PDF του ημερολογίου απόδειξης eIDAS
POST/api/v1/envelopes/{id}/embed-urlΕπιστρέφει το URL υπογραφής ενός παραλήπτη, μαζί με εξουσιοδότηση πλαισίου για την ζητούμενη προέλευση. Καλείται κατά τη στιγμή του κλικ: η εξουσιοδότηση ισχύει για δύο ώρες.
GET/api/v1/audit-anchors/{root}Δημόσιο : μεταδεδομένα ενός αγκυρωμένου αρχείου ελέγχου, ή αρχείο απόδειξης .ots με ?format=ots (χωρίς ταυτοποίηση)
POST/api/v1/audit-anchors/verifyΔημόσιο : επαλήθευση μιας καταχώρησης ελέγχου και της απόδειξής της έναντι της αγκυρωμένης ρίζας Merkle (χωρίς ταυτοποίηση, δεν αποκαλύπτει τίποτα)
GET/api/v1/envelopes/{id}/signed-documentΛήψη του υπογεγραμμένου PDF (μόλις COMPLETED)
GET/api/v1/envelopes/bulkΛίστα των μαζικών αποστολών σας
POST/api/v1/envelopes/bulkΜαζική αποστολή: δημιουργία N φακέλων από ένα πρότυπο και ένα CSV (μόνο Standard/Business)
GET/api/v1/envelopes/bulk/{id}Πρόοδος μαζικής αποστολής: μετρητές, αποτυχίες ανά σειρά, δημιουργημένοι φάκελοι
GET/api/v1/templatesΚαταχώρηση των επαναχρησιμοποιήσιμων προτύπων φακέλου
POST/api/v1/templatesΔημιουργία ενός προτύπου (έγγραφα, ρόλοι, τοποθετημένα πεδία)
GET/api/v1/workspacesΚαταχώρηση των χώρων εργασίας στους οποίους μπορείτε να δημιουργήσετε έναν φάκελο
POST/api/v1/sepa-mandatesΔημιουργία του PDF ενός εξουσιοδοτικού SEPA και του φακέλου DRAFT του, τα πεδία ήδη τοποθετημένα
POST/api/v1/payroll-adapters/normalizeΚανονικοποίηση ενός CSV μισθοδοσίας (Silae, Sage Paie, PayFit, Lucca) στη μορφή μαζικής αποστολής
POST/api/v1/ag-coproprieteΔημιουργία ενός φακέλου γενικής συνέλευσης συνδιοικησίας (αποφάσεις και ποσοστά συνιδιοκτησίας)
POST/api/v1/ag-copropriete/{envelopeId}/votesΚαταγραφή των ψήφων ενός συνιδιοκτήτη στις αποφάσεις της συνέλευσης
POST/api/v1/ag-copropriete/{envelopeId}/tallyΚαταμέτρηση της συνέλευσης: αποτέλεσμα ανά απόφαση, σταθμισμένο με τα ποσοστά συνιδιοκτησίας
GET/api/v1/videos/{videoId}Λήψη ενός βίντεο ταυτότητας που διατηρείται: δικαίωμα πρόσβασης RGPD (άρθρο 15)
GET/api/v1/webhooksΚαταχώρηση των webhooks
POST/api/v1/webhooksΕγγραφή ενός webhook: επιστροφή του μυστικού υπογραφής μόνο μία φορά
GET/api/v1/webhooks/{id}Ανάγνωση μιας συνδρομής webhook
PATCH/api/v1/webhooks/{id}Τροποποίηση του URL, των συμβάντων ή της ενεργού κατάστασης
DELETE/api/v1/webhooks/{id}Κατάργηση της εγγραφής του webhook
POST/api/v1/sealsΤοποθέτηση ενός εγκεκριμένου ηλεκτρονικού σφραγίδας σε ένα έγγραφο
GET/api/v1/seals/{id}Ανάγνωση της κατάστασης ενός σφραγίδας
GET/api/v1/seals/{id}/certificateΛήψη του πιστοποιητικού του σφραγίδας
GET/api/v1/payslips/workspacesΜισθολόγια: οι χώροι για τους οποίους αυτό το κλειδί διανέμει, κατέχει ή ανατίθεται από έναν πελάτη (λογιστικά γραφεία, διαχειριστές μισθοδοσίας)
GET/api/v1/payslips/employeesΜισθολόγια: το μητρώο των υπαλλήλων, με εκείνους που αρνήθηκαν την ηλεκτρονική παράδοση (οφειλόμενο έντυπο μισθολόγιο)
PUT/api/v1/payslips/employeesΜισθοδοτικά δελτία: προσθήκη ή ενημέρωση υπαλλήλων του μητρώου (ποτέ δεν αφαιρούνται)
POST/api/v1/payslipsΚατάθεση μισθοδοτικού δελτίου (PDF) στο χρηματοκιβώτιο ενός υπαλλήλου: σφραγισμένο, διατηρημένο 50 χρόνια, νέα προσπάθεια χωρίς διπλότυπο
GET/api/v1/payslipsΚαταχώριση των παραδοθέντων δελτίων, με την απόδειξη ανάγνωσής τους
GET/api/v1/keysΚαταχώριση των κλειδιών API
POST/api/v1/keysΔημιουργία κλειδιού API: το μυστικό εμφανίζεται μόνο μία φορά
PATCH/api/v1/keys/{id}Μετονομασία ή ανάκληση κλειδιού
DELETE/api/v1/keys/{id}Διαγραφή κλειδιού
GET/api/v1/billing/usageΚατανάλωση της τρέχουσας περιόδου και προβλεπόμενο κόστος
GET/api/v1/statusΚατάσταση υπηρεσίας
GET/api/v1/healthΈλεγχος υγείας: βάση δεδομένων, ουρά αναμονής και αποθήκευση αντικειμένων
GET/api/v1/openapiΠροδιαγραφή OpenAPI που μπορεί να διαβαστεί από μηχανή

Προτεινόμενα πλαίσια

Ένα πρότυπο καταχωρεί μία φορά για πάντα το PDF, τους ρόλους και τη θέση των πεδίων υπογραφής, στη συνέχεια επαναχρησιμοποιείται σε κάθε αποστολή: περάστε το αναγνωριστικό του στο templateId αντί του documentIds, και τα τοποθετημένα πεδία αντιγράφονται στον δημιουργημένο φάκελο.

  • • Τα πρότυπα δημιουργούνται από τον πίνακα ελέγχου (Πρότυπα → Νέο πρότυπο), όπου κατατίθεται το έγγραφο και στη συνέχεια τοποθετούνται τα πεδία με το ποντίκι — αυτό είναι ο απλούστερος τρόπος. Το API επιτρέπει επίσης να δημιουργηθούν με POST /api/v1/templates, παρέχοντας τα έγγραφα, τους ρόλους και τα πεδία· προσοχή, τα πεδία τοποθετούνται εκεί σε απόλυτες συντεταγμένες (σελίδα, x, y, πλάτος, ύψος), πρέπει λοιπόν να γνωρίζετε τη διάταξη του PDF.
  • • Σε ένα λογαριασμό που δεν έχει ακόμη καταχωρήσει κανένα πρότυπο, το GET /api/v1/templates επιστρέφει μια κενή λίστα. Αυτή είναι η κανονική συμπεριφορά, όχι ένα ελάττωμα ταυτοποίησης.
  • • Η λίστα περιέχει μόνο τα πρότυπα που ανήκουν στον χρήστη ιδιοκτήτη του κλειδιού API. Ένα πρότυπο που δημιουργήθηκε από έναν συνάδελφο δεν εμφανίζεται εκεί, ακόμη και εντός ενός κοινόχρηστου χώρου εργασίας: δημιουργήστε το κλειδί από τον λογαριασμό που κατέχει το πρότυπο.
  • • templateId και documentIds αποκλείουν αλλήλως: στείλτε το ένα ή το άλλο, ποτέ και τα δύο ούτε κανένα από τα δύο.
  • • Παρέχετε τουλάχιστον τόσους παραλήπτες SIGNER όσους ρόλους υπογραφής διαθέτει το πρότυπο, διαφορετικά η δημιουργία απορρίπτεται με 400. Το πεδίο signerCount που επιστρέφεται από τη λίστα υποδεικνύει τον αναμενόμενο αριθμό.
  • • Το επίπεδο υπογραφής του προτύπου κληρονομείται από τον φάκελο, εκτός αν το αίτημα μεταδίδει ρητά signatureLevel.
cURLbash
# 1. Discover the templates saved on this account.
curl -s https://certyneo.com/api/v1/templates \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx"

# {
#   "data": [
#     { "id": "cmdq7f4k80001s6y2h1xa9pl3", "name": "Contrat de prestation",
#       "signerCount": 2, "documentCount": 1, "signatureLevel": "SIMPLE" }
#   ],
#   "pagination": { "page": 1, "pageSize": 20, "total": 1, "pages": 1 }
# }
#
# An empty "data" array means no template exists on this account yet —
# create one from the dashboard, it is not an authentication problem.

# 2. Create the envelope FROM the template: no documentIds and no field
#    coordinates, both are carried by the template. Pass one SIGNER
#    recipient per signer role, in the template's role order.
curl -X POST https://certyneo.com/api/v1/envelopes \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "subject": "Contrat de prestation",
    "templateId": "cmdq7f4k80001s6y2h1xa9pl3",
    "recipients": [
      { "email": "client@example.com", "name": "Marie Dubois", "role": "SIGNER" },
      { "email": "legal@example.com", "name": "Paul Martin", "role": "SIGNER" }
    ]
  }'

# 3. The envelope is DRAFT at this point — POST /envelopes/{id}/send
#    dispatches it, exactly as in the quick-start above.

Από το Power Automate ή το Zapier

Η ενέργεια «Δημιουργία φακέλου» των συνδέσμων no-code δεν καλύπτει παρά την πορεία του προτύπου: το πεδίο Πρότυπο είναι υποχρεωτικό. Για ένα ad hoc έγγραφο που αλλάζει σε κάθε εκτέλεση, χρησιμοποιήστε την ενέργεια «Μεταφόρτωση εγγράφου» και στη συνέχεια μια ενέργεια HTTP χωρίς σύνδεσμο προς POST /api/v1/envelopes περνώντας το documentIds που επιστράφηκε.

Αποστολή εγγράφου: δύο αποδεκτές μορφές

POST /api/v1/documents δέχεται το αρχείο με δύο τρόπους, κατά επιλογή. Οι ίδιοι έλεγχοι εφαρμόζονται και στις δύο περιπτώσεις: επιτρεπόμενοι τύποι, όριο 50 Mo, επαλήθευση δυαδικής υπογραφής και ανάλυση κακόβουλου λογισμικού.

  • • Σε multipart/form-data, με ένα τμήμα που ονομάζεται file. Αυτή είναι η κλασική μορφή, αυτή του curl -F και της πλειοψηφίας των βιβλιοθηκών.
  • • Σε ακατέργαστο σώμα: τα byte του αρχείου αποτελούν το σώμα του αιτήματος και η κεφαλίδα Content-Type δίνει τον τύπο του (application/pdf για παράδειγμα). Χρήσιμο από ένα εργαλείο που μεταδίδει το περιεχόμενο όπως είναι, χωρίς να περιτυλίγει το αίτημα — αυτό κάνει ο σύνδεσμος Power Automate.
  • • Σε ακατέργαστο σώμα, το όνομα του αρχείου δεν έχει θέση στο σώμα: υποδείξτε το μέσω της κεφαλίδας X-File-Name ή της παραμέτρου ?fileName=. Χωρίς αυτό, το έγγραφο ονομάζεται σύμφωνα με τον τύπο του.
  • • Ένας μη υποστηριζόμενος τύπος απαντά 415 ονοματίζοντας τις δύο αποδεκτές μορφές, και ένα σώμα που ανακοινώνεται ως multipart αλλά δεν είναι αναγνώσιμο απαντά 400. Κανένα από τα δύο δεν είναι σφάλμα διακομιστή.
cURLbash
# a. multipart/form-data — the classic shape.
curl -X POST https://certyneo.com/api/v1/documents \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -F "file=@contrat.pdf;type=application/pdf"

# b. raw body — the file bytes ARE the body, typed by Content-Type.
#    The filename has nowhere to live in the body, so pass it as a header
#    (or ?fileName=). Without it the document is named after its type.
curl -X POST https://certyneo.com/api/v1/documents \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/pdf" \
  -H "X-File-Name: contrat.pdf" \
  --data-binary "@contrat.pdf"

# Both return the same 201 with the document id to pass as documentIds.

Τοποθέτηση των πεδίων ψηφιακής όρασης

Χωρίς πρότυπο, ένας φάκελος που δημιουργείται από documentIds δεν έχει κανένα προ-τοποθετημένο πεδίο: ο υπογράφων λαμβάνει το έγγραφο χωρίς θέση υπογραφής. Ο πίνακας fields, μεταδιδόμενος στην ίδια κλήση δημιουργίας, τοποθετεί κάθε πεδίο με ακρίβεια — είναι το ισοδύναμο, από την πλευρά του API, αυτού που ένα πρότυπο καταχωρεί μια φορά για πάντα.

  • • Οι συντεταγμένες είναι σε σημεία PDF, αρχή στην πάνω αριστερή γωνία της σελίδας και άξονας Y προς τα κάτω (μια σελίδα A4 μετρά 595 × 842 σημεία). x και y ορίζουν την πάνω αριστερή γωνία του πεδίου, width και height το μέγεθός του.
  • • pageNumber ξεκινά από 1, documentIndex ξεκινά από 0. Ένας αριθμός σελίδας πέρα από το έγγραφο δεν απορρίπτεται κατά τη δημιουργία: το πεδίο αγνοείται κατά την υπογραφή και δεν εμφανίζεται πουθενά — είναι το πρώτο πράγμα που πρέπει να ελέγξετε όταν λείπει ένα πεδίο από την κλήση.
  • • recipientEmail πρέπει να αντιστοιχεί σε έναν από τους παραλήπτες του ίδιου αιτήματος, χωρίς διάκριση πεζών και κεφαλαίων. Διαφορετικά η δημιουργία αποτυγχάνει παραθέτοντας όλες τις λανθασμένες γραμμές, γεγονός που αποφεύγει να τις διορθώνετε μία προς μία.
  • • fields και templateId αποκλείουν αλλήλως: ένα πρότυπο φέρει ήδη τη δική του διάταξη. Ο πίνακας fields χρησιμοποιείται επομένως μόνο με documentIds.
  • • Αποδεκτοί τύποι: SIGNATURE, INITIALS, DATE_SIGNED, TEXT, CHECKBOX και RADIO_GROUP. required είναι true από προεπιλογή· placeholder και dateFormat είναι προαιρετικά, και options διατηρείται μόνο για RADIO_GROUP.
  • • Ένας φάκελος δέχεται το πολύ 100 πεδία, 20 έγγραφα και 50 παραλήπτες — οι όρια του σχεδίου σας ενδέχεται να είναι χαμηλότερα.
cURLbash
# Ad-hoc envelope WITH pre-placed fields — no template involved.
# Coordinates are PDF points, origin TOP-LEFT of the page, +Y downwards
# (A4 = 595 x 842 pt). x / y are the field box's top-left corner.
#
# The last field is positioned by ANCHOR instead of by eye: the server
# locates "Signature du client" in the PDF and computes the spot. x / y
# stay required there — they are the fallback if the text is not found.
curl -X POST https://certyneo.com/api/v1/envelopes \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "subject": "Contrat de prestation",
    "documentIds": ["cmdq7f4k80001s6y2h1xa9pl3"],
    "recipients": [
      { "email": "client@example.com", "name": "Marie Dubois", "role": "SIGNER" }
    ],
    "fields": [
      { "recipientEmail": "client@example.com", "documentIndex": 0,
        "pageNumber": 2, "fieldType": "SIGNATURE",
        "x": 90, "y": 640, "width": 180, "height": 44 },
      { "recipientEmail": "client@example.com", "documentIndex": 0,
        "pageNumber": 2, "fieldType": "DATE_SIGNED",
        "x": 320, "y": 640, "width": 140, "height": 30,
        "dateFormat": "DD/MM/YYYY" },
      { "recipientEmail": "client@example.com", "documentIndex": 0,
        "pageNumber": 2, "fieldType": "TEXT",
        "x": 90, "y": 700, "width": 200, "height": 30,
        "placeholder": "Fonction", "required": false },
      { "recipientEmail": "client@example.com", "documentIndex": 0,
        "pageNumber": 2, "fieldType": "SIGNATURE",
        "anchorText": "Signature du client", "anchorPlacement": "below",
        "anchorIndex": 0,
        "x": 90, "y": 640, "width": 180, "height": 44 }
    ]
  }'

# The envelope is DRAFT at this point — POST /envelopes/{id}/send
# dispatches it, exactly as in the quick-start above.

Αγκυρες κειμένου: τοποθέτηση ενός πεδίου χωρίς γνώση των συντεταγμένων

Αντί για συντεταγμένες, ένα πεδίο μπορεί να αναφέρει ένα κείμενο που είναι τυπωμένο στο έγγραφο: anchorText το εντοπίζει στο PDF και ο διακομιστής υπολογίζει τη θέση κατά τη δημιουργία. Αυτή είναι η κατάσταση που προτιμάται όταν το έγγραφο αναδημιουργείται σε κάθε αποστολή — mail merge, γεννήτρια συμβάσεων — καθώς η διάταξη αλλάζει ενώ η αναφορά «Υπογραφή του πελάτη» παραμένει. anchorPlacement υποδεικνύει από ποια πλευρά του κειμένου τοποθετείται το πεδίο (right από προεπιλογή, ή below, above ή left) και anchorIndex επιλέγει την εμφάνιση όταν το κείμενο εμφανίζεται πολλές φορές.

x και y παραμένουν υποχρεωτικά ακόμα και με μια αγκύρα: χρησιμεύουν ως εφεδρεία. Μια αγκύρα που δεν βρέθηκε δεν προκαλεί αποτυχία της δημιουργίας — το πεδίο διατηρεί τη κυριολεκτική θέση που παρείχατε, χωρίς σφάλμα ή προειδοποίηση στην απάντηση. Υποδείξτε λοιπόν μια εύλογη εφεδρεία αντί για 0,0 και επαληθεύστε την απόδοση σε μια πρώτη αποστολή.

Ενσωματωμένη υπογραφή: υπογραφή χωρίς να αφήσετε την εφαρμογή σας

Ο πελάτης σας συμβουλεύεται και υπογράφει το έγγραφό του από τη δική σας διεπαφή. Η τελετή ανοίγει σε ένα παράθυρο πάνω από τη σελίδα σας και επιστρέφει αυτόματα όταν ολοκληρωθεί. Στη σερβερ πλευρά, δεν υπάρχει τίποτα νέο: δημιουργείτε το φάκελο όπως συνήθως εισάγοντας redirectUrl, στη συνέχεια ανατίθετε στο SDK το URL υπογραφής του παραλήπτη.

  • • Καλέστε το Certyneo.sign() απευθείας στο χειριστή κλικ σας και περάστε την κλήση διακομιστή σας μέσω getUrl. Ένα await πριν από το sign() βγαίνει από τη χειρονομία χρήστη: το Safari και το Firefox τότε μπλοκάρουν το παράθυρο. Το SDK το ανοίγει αμέσως και το φορτώνει όταν η υπόσχεσή σας αναλύεται.
  • • Το redirectUrl είναι το κανάλι επιστροφής. Εκεί επιστρέφουμε τον υπογράφοντα προσθέτοντας certyneo_status (completed ή declined) και certyneo_envelope. Φορτώστε το ίδιο script σε αυτή τη σελίδα επιστροφής: αυτό είναι που ειδοποιεί το παράθυρο του portal που παρέμεινε ανοικτό πίσω.
  • • Σε ενσωματωμένη λειτουργία, οι δικές μας κλήσεις δράσης καταστέλλονται. Ο πελάτης σας δεν βλέπει ποτέ πρόσκληση να δημιουργήσει λογαριασμό Certyneo.
  • • Εάν ο περιηγητής αρνηθεί το παράθυρο, το SDK αλλάζει αυτόματα σε ανακατεύθυνση πλήρους σελίδας. Το ταξίδι είναι πανομοιότυπο για τον υπογράφοντα και η σελίδα επιστροφής σας λαμβάνει ακριβώς τις ίδιες παραμέτρους.
  • • Δεν υπάρχει σκόπιμα κανένα callback «ο χρήστης εγκατέλειψε»: η κατάσταση του παραθύρου δεν είναι αναγνώσιμη από τη σελίδα σας, και τέτοιο callback θα ενεργοποιούνταν λανθασμένα. Μια υπογραφή που δεν φτάνει παραμένει σε αναμονή έως το webhook.
JavaScriptjavascript
// 1. Your server creates and sends the envelope, then hands the browser the
//    recipient's signing URL. Nothing new on the API side:
//      POST /api/v1/envelopes        { …, "redirectUrl": "https://your-app.com/quote/42/signed" }
//      POST /api/v1/envelopes/{id}/send   → recipients[].accessToken
//      signingUrl = "https://certyneo.com/sign/" + accessToken

// 2. On your quote page — load the SDK once:
//      <script src="https://certyneo.com/embed.js"></script>

document.querySelector("#sign").addEventListener("click", () => {
  Certyneo.sign({
    // Called AFTER the window is already open, so no popup blocker ever
    // sees a delay between the click and window.open.
    getUrl: () =>
      fetch("/api/quote/42/signature", { method: "POST" })
        .then((r) => r.json())
        .then((d) => d.signingUrl),

    onCompleted: (e) => showConfirmation(e.envelopeId),
    onDeclined: () => showDeclined(),
    onError: (e) => showError(e),
  });
});

// 3. On https://your-app.com/quote/42/signed — your return page — load the
//    same script and render a short confirmation. It relays the outcome to
//    the portal window behind it, then closes itself.

Το γεγονός του περιηγητή δεν είναι απόδειξη υπογραφής

onCompleted είναι ένα σήμα εμφάνισης, που εκπέμπεται από ένα πρόγραμμα περιήγησης, επομένως μπορεί να παραποιηθεί από οποιονδήποτε από την κονσόλα του. Μην ποτέ αλλάξετε μια υπόθεση σε « υπογεγραμμένη » βάσει αυτού: χρησιμοποιήστε το για ανανέωση της οθόνης, και βασιστείτε στο υπογεγραμμένο webhook envelope.completed που λαμβάνεται από τον διακομιστή σας για την πραγματική κατάσταση. Αυτό είναι το κλασικό παγίδα των ολοκληρώσεων πληρωμών, και επαναλαμβάνεται εδώ με τον ίδιο τρόπο.

Ανάπτυξη στο σταθμό σας

Με ένα κλειδί δοκιμής, το redirectUrl δέχεται http://localhost (και 127.0.0.1): ανεβάζετε ολόκληρο το ταξίδι στη μηχανή σας πριν τη ανάπτυξη. Ένα πραγματικό κλειδί το αρνείται, ώστε κανένα φάκελο παραγωγής να μην επιστρέφει έναν πραγματικό υπογράφοντα σε ένα μηχάνημα που δεν είναι δικό του.

Εμφάνιση της τελετής στη σελίδα σας

Η λειτουργία πλαισίου εμφανίζει την υπογραφή μέσα στη διεπαφή σας, χωρίς παράθυρο. Απαιτεί ένα επιπλέον βήμα σε σχέση με τη λειτουργία παραθύρου: να αποδείξετε ότι ο ιστότοπος που θα το εμφανίζει σας ανήκει. Αυτό είναι αυτό που εμποδίζει ένα τρίτο μέρος να πλαισιώσει τις τελετές μας για να εξαπατήσει τους πελάτες σας.

  • • Δηλώστε τον ιστότοπό σας στις Ρυθμίσεις → Ενσωματωμένη υπογραφή και, στη συνέχεια, δημοσιεύστε την καταγεγραμμένη εγγραφή DNS. Μια ακριβής διεύθυνση: ένας υποτομέας ή μια διαφορετική θύρα θεωρούνται ως ένας άλλος ιστότοπος.
  • • Σε κάθε υπογραφή, ζητήστε ένα νέο URL μέσω POST /api/v1/envelopes/{id}/embed-url. Φέρει την εξουσιοδότηση εμφάνισης και ισχύει για δύο ώρες, το οποίο αντιστοιχεί στη στιγμή του κλικ, όχι στη δημιουργία του φακέλου.
  • • Δύο διαδρομές δεν μπορούν να λάβουν χώρα σε ένα πλαίσιο: η προσόντα υπογραφή, της οποίας η επαλήθευση ταυτότητας αρνείται να πλαισιωθεί με τη σειρά της, και η πληρωμή κατά την υπογραφή. Και στις δύο περιπτώσεις ο υπογράφων κατευθύνεται σε ένα πλήρες παράθυρο.
  • • Η ένδειξη «Τροφοδοσία από το Certyneo» εξαφανίζεται από το πλαίσιο από το σχέδιο Business και πάνω. Η λειτουργία πλαισίου είναι περιλαμβανόμενη από το σχέδιο Standard.
JavaScriptjavascript
// Mode cadre : la cérémonie s'affiche DANS votre page.
//
// 1. Déclarez votre site une fois pour toutes dans Réglages → Signature
//    intégrée, et publiez l'enregistrement DNS qu'on vous y donne.
//
// 2. À chaque signature, votre serveur demande une URL fraîche. Elle porte
//    l'autorisation qui permet au navigateur d'afficher la cérémonie chez
//    vous, et vaut deux heures :
//
//      POST /api/v1/envelopes/{id}/embed-url
//      { "origin": "https://portail.exemple.fr" }
//      -> { "signingUrl": "…", "expiresAt": "…" }

Certyneo.sign({
  mode: "iframe",
  el: "#zone-signature",        // sélecteur ou nœud de votre page

  getUrl: () =>
    fetch("/api/devis/42/signature", { method: "POST" })
      .then((r) => r.json())
      .then((d) => d.signingUrl),

  onCompleted: (e) => afficherConfirmation(e.envelopeId),
  onDeclined: () => afficherRefus(),
});

// Le cadre parle à votre page par postMessage — pas besoin de page de retour,
// contrairement au mode fenêtre.

Υπογράψτε χωρίς να αποσταλεί κανένα e-mail

Ένα πορτάλ που εμφανίζει την τελετή στο δικό του δεν έχει συχνά ανάγκη της πρόσκλησης μας: φτάνει δίπλα στη δική του διαδρομή και προσφέρει έναν λογαριασμό σε έναν πελάτη που δεν τον θέλει. Δώστε την τιμή NONE στο κανάλι ειδοποίησης ενός παραλήπτη και δεν του αποστέλλεται πλέον τίποτα — εσείς τον οδηγείτε στην υπογραφή του.

  • • Η ρύθμιση είναι ανά παραλήπτη, όχι ανά φάκελο: μπορείτε να σιωπήσετε τον πελάτη που φιλοξενείτε και να κρατήσετε το e-mail για έναν εξωτερικό συνυπογράφοντα, που δεν έχει πορτάλ.
  • • Είναι δεσμευμένο για υπογράφοντες και εγκριτές, τους μόνους στους οποίους έχετε ένα σύνδεσμο να παραδώσετε. Το διαβάζετε στην απάντηση της δημιουργίας και της αποστολής, ή ζητάτε ένα φρέσκο URL κατά τη στιγμή του κλικ στο POST /api/v1/envelopes/{id}/embed-url.
  • • Οι αυτόματες υπενθυμίσεις σταματούν από μόνες τους για αυτόν τον παραλήπτη: δεν του έχουμε ποτέ γράψει, δεν αρχίζουμε με μια υπενθύμιση. Οι άλλοι παραλήπτες συνεχίζουν να υπενθυμίζονται κανονικά.
  • • Το πιστοποιητικό υπογραφής το αναφέρει, παραλήπτη προς παραλήπτη. Ένας φάκελος αποδείξεων που θα σιωπούσε σχετικά με αυτό θα άφηνε να φανεί ότι αυτός ο υπογράφων έλαβε από εμάς μια πρόσκληση που δεν υπήρξε ποτέ.
JSONjson
POST /api/v1/envelopes

{
  "subject": "Mandat de gestion",
  "documentIds": ["doc_8f2c1a4b9e7d"],
  "recipients": [
    {
      "email": "client@exemple.fr",
      "name": "Camille Client",
      "role": "SIGNER",
      "notificationChannel": "NONE"
    },
    {
      "email": "notaire@exemple.fr",
      "name": "Maître Notaire",
      "role": "SIGNER"
    }
  ]
}

// La réponse rend le lien de chaque signataire :
//
//   "recipients": [
//     { "email": "client@exemple.fr",  "accessToken": "…",
//       "notificationChannel": "NONE"  },
//     { "email": "notaire@exemple.fr", "accessToken": "…",
//       "notificationChannel": "EMAIL" }
//   ]
//
// Le client ne reçoit rien : vous l'emmenez sur sa signature depuis votre
// portail. Le notaire, lui, reçoit son invitation comme d'habitude.

Εμφάνιση του ονόματος του πελάτη σας ως αποστολέα

Από προεπιλογή, ο υπογράφων διαβάζει το όνομα του κατόχου του κλειδιού API. Εάν κάνετε υπογραφή εγγράφων πολλών εταιρειών με ένα μόνο κλειδί, περάστε το πεδίο sender κατά τη δημιουργία του φακέλου: η σελίδα υπογραφής και τα μηνύματα ηλεκτρονικής αλληλογραφίας πρόσκλησης και υπενθύμισης εμφανίζουν τότε το όνομα της σχετικής εταιρείας.

  • • Δεσμευμένο για το σχέδιο Business και πέρα. Σε ένα χαμηλότερο σχέδιο, η δημιουργία αρνείται αντί να αφήσει τον υπογράφοντα να διαβάσει ένα όνομα διαφορετικό από αυτό που αναμένεται.
  • • Το όνομα είναι μια εμφάνιση: το πιστοποιητικό και ο ίχνος ελέγχου διατηρούν τον πραγματικό αποστολέα, και τα μηνύματα ηλεκτρονικής αλληλογραφίας προέρχονται πάντα από το Certyneo.
  • • Η διεύθυνση είναι προαιρετική. Χωρίς αυτήν, ο υπογράφων βλέπει μόνο το όνομα, ποτέ τη διεύθυνση του κατόχου του κλειδιού.
JSONjson
POST /api/v1/envelopes

{
  "subject": "Devis 2026-118",
  "documentIds": ["doc_8f2c1a4b9e7d"],
  "recipients": [
    { "email": "client@exemple.fr", "name": "Camille Client", "role": "SIGNER" }
  ],
  "sender": {
    "name": "1.2.3. Panneaux Solaires",
    "email": "devis@123-panneaux-solaires.fr"
  }
}

Επιβεβαίωση

Κάθε πρόσφατη ζήτηση είναι μεταξύ των API κλειδιών στον κεφάλαιο Authorization. Τα κλείδια δημιουργούνται από Συσχετισμές → Κλειδιά API και εμφανίζονται μόνο ποτέ μια φορά.

HTTPhttp
GET /api/v1/account/me HTTP/1.1Host: certyneo.com
Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx

# 200 OK
{ "data": { "id": "usr_…", "email": "you@example.com", "plan": "BUSINESS", "environment": "live" } }
  • • Format: sk_live_… σε διαστάσεις παραγωγής, sk_test_… για τη λίθινο. Κεφάλαιο: Authorization: Bearer <κλείδωμα>.
  • • Επιτόκια: envelopes, documents, webhooks, seals - σε ανάγνωση (:read) ή γραφή (:write). Η γραφή περιλαμβάνει την ανάγνωση; Το επιτόκιο * δίνει όλα τα δικαιώματα.
  • • Τα κλειδιά sk_test_ δημιουργούν πόρους σε sandbox, εξαιρούμενα από την ποσόστωση και τη χρέωση. Δεν αποστέλλεται πραγματικό email στον παραλήπτη, εκτός εάν η διεύθυνσή του ταιριάζει με το email του λογαριασμού αποστολής — χρήσιμο για να δοκιμάσετε ολόκληρη τη ροή στον εαυτό σας.
  • • Σφάλματα: 401 άκυρο κλείδωμα, 403 παραβιάση επιτόκιου, 429 ύψος ταχύτητας ανεξέρχεται, 402 μήνικος κλήρος ορίζεται.

Τύπος παρουσιάσεων

Ενα γνώση πριν από τη συμπλήρωση του υποψήφιου: οι συγκεκριμένες εγχώριες είναι κατάλληλες σε αντικείμενο data, ενώ τα μόνιμα πόρους επιστρέφονται ξεχωριστά. Εισαγώντας response.data.data σε ένα μόνιμο πόρο, επιστρέφει undefined.

Συγκεκριμένηjson
// GET /api/v1/envelopes
// Collections are WRAPPED in a "data" array.
{
  "data": [
    { "id": "env_abc123", "subject": "Contrat", "status": "SENT" }
  ]
}
Μόνιμος πόροςjson
// GET /api/v1/envelopes/{id}
// Single resources are returned FLAT — no "data" envelope.
{
  "id": "env_abc123",
  "subject": "Contrat",
  "status": "COMPLETED",
  "recipients": [ /* … */ ]
}

Όρια ταχύτητας

Τα όρια εγγυώνται σταθερή ποιότητα υπηρεσίας για όλους τους πελάτες. Αν χρειάζεστε περισσότερα, επικοινωνήστε με ημάς.

  • • 100 αιτήματα ανά λεπτό ανά API κλειδί
  • • Burst ανεκτό έως 200 αιτήματα σε λιγότερο από 10s
  • • Απάντηση 429 με κεφαλίδα Retry-After που υποδεικνύει την καθυστέρηση σε δευτερόλεπτα

Προχωρήστε περαιτέρω