Gå till huvudinnehål
Certyneo
Offentligt API v1

Integrera elektronisk signatur i din stack

Skicka kuvert, följ signaturer, ta emot webhooks. Enkelt REST API, OpenAPI 3.0, curl/Node/Python-exempel — allt för att koppla Certyneo till din HRIS, CRM eller affärsmjukvara på några timmar.

Snabbstart

Tre steg: skapa en API-nyckel från inställningarna, koda din PDF i base64, skicka. Svaret innehåller `signUrl` som du kan dela direkt med mottagaren.

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"])

Prova API:et från dina verktyg

Postman-samlingen och RapidAPI-arket genereras från OpenAPI-specifikationen som också dokumenterar denna sida. De tre förblir därför justerade med det verkliga API:et, endpoint för endpoint, snarare än att divergera vid första tillägg.

Postman-samling

De 25 förfrågningarna organiserade efter domän — kuvert, dokument, mallar, sigill, webhooks — med ett exempel på brödtext och svar för var och en. Klistra in din nyckel i samlingens apiKey-variabel och kör sedan GET /health: den kräver ingen autentisering och bekräftar att din konfiguration är bra före det första autentiserade anropet.

RapidAPI-ark

Samma katalog över endpoints, testbar direkt från webbläsaren. Testbänken förväntar två distinkta huvuden: RapidAPI-nyckeln som plattformen tilldelar dig och din Certyneo-nyckel i Authorization — det är den andra som faktiskt autentiserar anropet.

Kuvert

Skapande, sändning, statusövervakning, annullering. Ett kuvert kan innehålla flera dokument och flera undertecknare (parallell eller sekventiell).

Webbooks

Alla kuvert- och mottagarhändelser (`envelope.sent`, `recipient.signed`, `envelope.completed`…) levererade till din valda URL — komplett lista på /developers/webhooks. HMAC SHA-256 på varje payload för att verifiera ursprunget.

Enkel autentisering

Bearer-token. En nyckel per miljö (test / prod). Återkallningsbar omedelbar. Gräns 100 req/min/nyckel, burst på 200, ren 429 med Retry-After-rubrik.

Tillgängliga endpoints

De 52 offentliga vägen: konto, dokument, kuvert, mallar, webhooks, elektroniska sigill, API-nycklar och fakturering. Alla accepterar en Bearer-token och returnerar JSON.

MetodSökvägBeskrivning
GET/api/v1/account/meAutentiserad anroparidentitet (id, e-post, plan) : identifieringstestning utan obligatorisk omfattning
GET/api/v1/sandboxRäkna data som skapats med testnycklar (raderas automatiskt efter 30 dagar)
DELETE/api/v1/sandboxRadera alla data som skapats med testnycklar, utan att röra riktiga data
POST/api/v1/documentsLadda upp en PDF (multipart) : returnerar dokumentets id
GET/api/v1/documentsLista dokument
GET/api/v1/documents/{id}Läs ett dokuments metadata
DELETE/api/v1/documents/{id}Ta bort ett dokument
GET/api/v1/envelopesLista kuvert (filtrera med ?status= och ?limit=)
POST/api/v1/envelopesSkapa ett kuvert (status DRAFT) : från ett templateId eller dokumentIds med en valfri fields-array
GET/api/v1/envelopes/{id}Läs ett kuvert status
PATCH/api/v1/envelopes/{id}Ändra ett DRAFT-kuvert
DELETE/api/v1/envelopes/{id}Ta bort ett DRAFT-kuvert (409 när det har skickats : avbryt det istället)
POST/api/v1/envelopes/{id}/sendSkicka ett DRAFT-kuvert : skickar inbjudningar
POST/api/v1/envelopes/{id}/voidAvbryt ett skickat kuvert som ännu inte är helt signerat : väntande undertecknare meddelas
GET/api/v1/envelopes/{id}/audit-trailLadda ned PDF för eIDAS-revisionsspår
POST/api/v1/envelopes/{id}/embed-urlReturnerar signeringswebbadressen för en mottagare, tillsammans med en ramväxlingsauktorisering för den begärda ursprunget. Anropas vid klick: auktoriseringen är giltig i två timmar.
GET/api/v1/audit-anchors/{root}Offentlig : metadata för en förankrad revisionsbatch eller beviisfil .ots med ?format=ots (utan autentisering)
POST/api/v1/audit-anchors/verifyOffentlig : verifiera en revisionspost och dess bevis mot den förankrade Merkle-roten (utan autentisering, avslöjar ingenting)
GET/api/v1/envelopes/{id}/signed-documentLadda ned signerad PDF (när COMPLETED)
GET/api/v1/envelopes/bulkLista dina massutskick
POST/api/v1/envelopes/bulkMassutskick: skapa N kuvert från en mall och en CSV (endast Standard/Business)
GET/api/v1/envelopes/bulk/{id}Framsteg för massutskick: räknare, fel per rad, skapade kuvert
GET/api/v1/templatesLista återanvändbara kuvertmallar
POST/api/v1/templatesSkapa en mall (dokument, roller, placerade fält)
GET/api/v1/workspacesLista arbetsytorna där du kan skapa ett kuvert
POST/api/v1/sepa-mandatesGenerera PDF för ett SEPA-mandat och dess DRAFT-kuvert, fält redan placerade
POST/api/v1/payroll-adapters/normalizeNormalisera en löneavräknings-CSV (Silae, Sage Paie, PayFit, Lucca) till massutskickets format
POST/api/v1/ag-coproprieteSkapa ett kuvert för bostadsrättsstämma (beslut och andelar)
POST/api/v1/ag-copropriete/{envelopeId}/votesRegistrera en bostadsrättshavares röster på stämmans beslut
POST/api/v1/ag-copropriete/{envelopeId}/tallyRäkna upp stämman: resultat per beslut, vägt efter andelar
GET/api/v1/videos/{videoId}Ladda ner en bevarad identitetsvideo: åtkomsträttighet GDPR (art. 15)
GET/api/v1/webhooksLista webhooks
POST/api/v1/webhooksRegistrera en webhook: returnerar signeringshemligheteten endast en gång
GET/api/v1/webhooks/{id}Läs en webhook-prenumeration
PATCH/api/v1/webhooks/{id}Ändra URL, händelser eller aktivt tillstånd
DELETE/api/v1/webhooks/{id}Avbryt webhookens prenumeration
POST/api/v1/sealsApplicera en kvalificerad elektronisk segling på ett dokument
GET/api/v1/seals/{id}Läs status för en segling
GET/api/v1/seals/{id}/certificateLadda ner siegelns certifikat
GET/api/v1/payslips/workspacesLönespecifikationer: de utrymmen för vilka denna nyckel distribuerar, innehas eller delegeras av en klient (redovisningsbyråer, löneadministratörer)
GET/api/v1/payslips/employeesLönespecifikationer: registret över anställda, med de som har vägrat elektronisk leverans (pappersspecifikation förfallen)
PUT/api/v1/payslips/employeesLönespecifikationer: lägg till eller uppdatera anställda i registret (tar aldrig bort någon)
POST/api/v1/payslipsLeverera en lönespecifikation (PDF) i en anställds valv: förseglar, bevarad i 50 år, försök igen utan dubbletter
GET/api/v1/payslipsVisa en lista över levererade lönespecifikationer tillsammans med deras visningsbevis
GET/api/v1/keysVisa en lista över API-nycklar
POST/api/v1/keysSkapa en API-nyckel: hemligheten visas endast en gång
PATCH/api/v1/keys/{id}Byt namn på eller återkalla en nyckel
DELETE/api/v1/keys/{id}Ta bort en nyckel
GET/api/v1/billing/usageFörbrukning för innevarande period och beräknad kostnad
GET/api/v1/statusTjänststatus
GET/api/v1/healthHälsokontroll: databas, kö och objektlagring
GET/api/v1/openapiOpenAPI-specifikation maskinläsbar

Modell för innehållskapsul

En mall registrerar en gång för alla PDF-filen, rollerna och placeringen av signeringsfält, och återanvänds sedan vid varje sändning: skicka dess identifierare i templateId istället för documentIds, och de positionerade fälten kopieras om på det skapade kuvertet.

  • • Mallar skapas från instrumentpanelen (Mallar → Ny mall), där du överför dokumentet och placerar sedan fälten med musen — det är det enklaste sättet. API:et tillåter också att skapa dem via POST /api/v1/templates, genom att tillhandahålla dokument, roller och fält; notera att fält där positioneras i absoluta koordinater (sida, x, y, bredd, höjd), så du måste känna till PDF:ens layout.
  • • På ett konto som ännu inte har registrerat någon mall returnerar GET /api/v1/templates en tom lista. Det är normalt beteende, inte en autentiseringsfel.
  • • Listan innehåller endast mallar som tillhör användaren som äger API-nyckeln. En mall som skapats av en kollega finns inte i listan, även inom en delad arbetsyta: generera nyckeln från kontot som äger mallen.
  • • templateId och documentIds är ömsesidigt uteslutande: skicka antingen det ena eller det andra, aldrig båda eller inget av dem.
  • • Ange minst lika många SIGNER-mottagare som mallen har undertecknarroller, annars nekas skapandet med 400. Fältet signerCount som returneras av listan anger det förväntade antalet.
  • • Mallens signeringsnivå ärvs av kuvertet, såvida inte begäran uttryckligen skickar 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.

Från Power Automate eller Zapier

Åtgärden "Skapa ett kuvert" för våra no-code-anslutningar täcker endast mallvägen: fältet Mall är obligatoriskt där. För ett ad hoc-dokument som ändras vid varje körning, använd åtgärden "Ladda upp ett dokument" och sedan en rå HTTP-åtgärd till POST /api/v1/envelopes genom att skicka det returnerade documentIds.

Sändning av dokument: två godkända former

POST /api/v1/documents accepterar filen på två sätt, efter eget val. Samma kontroller gäller i båda fallen: tillåtna typer, gräns på 50 MB, verifiering av binär signatur och antivirusanalys.

  • • I multipart/form-data, med en del som heter file. Det är den klassiska formen, den för curl -F och de flesta biblioteken.
  • • I rå brödtext: filens oktetter utgör begärandets brödtext, och Content-Type-huvudet anger dess typ (application/pdf till exempel). Användbar från ett verktyg som överför innehållet som det är, utan att linda in begäran — det är vad Power Automate-kopplingen gör.
  • • I raw body är filnamnet inte på plats i body: ange det via X-File-Name-huvudet eller parametern ?fileName=. Utan det namnges dokumentet efter sin typ.
  • • En icke-stödd typ svarar 415 och namnger de två accepterade formaten, och en body som annonseras som multipart men inte är läsbar svarar 400. Ingen av dessa är ett serverfel.
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.

Placering av signaturfält

Utan mall skapar ett kuvert från documentIds inga förpositionerade fält: mottagaren får dokumentet utan någon signeringsplats. Matrisen fields, överfördl i samma skapelseanrop, placerar varje fält på punkten — det är motsvarigheten på API-sidan till vad en mall sparar en gång för alla.

  • • Koordinaterna är i PDF-poäng, ursprung i övre vänstra hörnet av sidan och Y-axel nedåt (en A4-sida mäter 595 × 842 poäng). x och y anger övre vänstra hörnet av fältet, width och height dess storlek.
  • • pageNumber börjar på 1, documentIndex börjar på 0. Ett sidnummer bortom dokumentet avvisas inte vid skapelse: fältet ignoreras vid underteckningstillfället och visas inte någonstans — det är det första att kontrollera när ett fält saknas i anropet.
  • • recipientEmail måste matcha en av mottagarna från samma anrop, utan skiftlägeskänslighet. Annars misslyckas skapelsen genom att lista alla felaktiga rader, vilket undviker att korrigera dem en efter en.
  • • fields och templateId utesluter varandra: en mall bär redan sin egen layout. Matrisen fields används därför bara med documentIds.
  • • Accepterade typer: SIGNATURE, INITIALS, DATE_SIGNED, TEXT, CHECKBOX och RADIO_GROUP. required är sant som standard; placeholder och dateFormat är valfria, och options beaktas bara för RADIO_GROUP.
  • • Ett kuvert accepterar högst 100 fält, 20 dokument och 50 mottagare — din plans gränser kan vara lägre.
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.

Textankar: placera ett fält utan att känna till koordinaterna

I stället för koordinater kan ett fält citera en text som är tryckt i dokumentet: anchorText letar upp det i PDF:en och servern beräknar positionen vid skapelse. Det är läget att föredra när dokumentet återskapas vid varje sändning — kopplingsbrev, kontraktsgenerator — eftersom layouten ändras medan anmärkningen "Kundens signatur" förblir. anchorPlacement anger på vilken sida av texten fältet placeras (right som standard, annars below, above eller left) och anchorIndex väljer förekomsten när texten visas flera gånger.

x och y förblir obligatoriska även med ett ankar: de fungerar som fallback. Ett ankar som inte hittas orsakar inte att skapelsen misslyckas — fältet behåller den bokstavliga positionen du angav, utan fel eller varning i svaret. Ange därför ett rimligt fallback i stället för 0,0 och verifiera renderingen vid en första sändning.

Inbäddad signering: signera utan att lämna din applikation

Din klient konsulterar och signerar sitt dokument från ditt eget gränssnitt. Ceremonin öppnas i ett fönster över din sida och återvänder till dig automatiskt när den är klar. På serversidan inget nytt: du skapar kuvertet som vanligt genom att ange redirectUrl, sedan överlåter du SDK:n mottagarens signerings-URL.

  • • Anropa Certyneo.sign() direkt i din klickhanterare och skicka ditt serversamtal via getUrl. En await före sign() kommer ur användarens gest: Safari och Firefox blockerar då fönstret. SDK:n öppnar det omedelbar och laddar det när ditt löfte löses.
  • • redirectUrl är returkanalen. Vi skickar tillbaka signeraren dit genom att lägga till certyneo_status (completed eller declined) och certyneo_envelope. Ladda samma skript på denna returnsida: det är det som meddelar portalfönstret som förblir öppet bakom.
  • • I inbäddat läge undertrycks våra egna handlingsuppmaning. Din klient ser aldrig en inbjudan att skapa ett Certyneo-konto.
  • • Om webbläsaren vägrar fönstret, växlar SDK:n automatiskt till fullsida omdirigering. Vägen är identisk för signeraren och din returnsida får exakt samma parametrar.
  • • Det finns avsiktligt ingen återanrop om "användaren övergav det": fönstrets tillstånd är inte läsbart från din sida, och ett sådant återanrop skulle utlösas felaktigt. En signatur som inte kommer fram förblir väntande tills 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.

Webbläsarhändelsen är inte ett signaturbevis

onCompleted är en visningssignal, utgiven av en webbläsare, därför förfalskningsbar av vem som helst från sin konsol. Byt aldrig en mapp till "signerad" på denna grund: använd den för att uppdatera skärmen, och förlita dig på webhook signerad envelope.completed mottagen av din server för verkligt tillstånd. Det är den klassiska fällan för betalningsintegrationer, och den upprepas identiskt här.

Utveckla på din maskin

Med en testnyckél accepterar redirectUrl http://localhost (och 127.0.0.1): du bygger hela vägen på din maskin innan du distribuerar. En verklig nyckel vägrar det, så att ingen produktionskonvolut skickar en verklig signerare tillbaka till en maskin som inte är hans egen.

Visa ceremonin på din sida

Ramläget visar signaturen inuti ditt gränssnitt, utan fönster. Det kräver ett steg mer än fönsterläget: att bevisa att webbplatsen som visar den tillhör dig. Det är det som förhindrar en tredje part från att rama in våra ceremonier för att lura dina kunder.

  • • Deklarera din webbplats i Inställningar → Integrerad signatur och publicera sedan DNS-posten som anges. En exakt adress: en underdomän eller en annan port räknas som en annan webbplats.
  • • Vid varje signatur, begär en färsk URL via POST /api/v1/envelopes/{id}/embed-url. Den bär visningsauktoriseringen och är giltig i två timmar, vilket motsvarar klickögonblicket, inte skapandet av kuvertet.
  • • Två arbetsflöden kan inte köras inom en ram: kvalificerad signatur, vars identitetsverifiering vägrar att ramas in i sin tur, och betalning vid signering. I båda fallen dirigeras undertecknaren till ett fullständigt fönster.
  • • Anmärkningen "Drivs av Certyneo" försvinner från ramen från och med Business-planen. Själva ramläget är inkluderat redan från Standard-planen.
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.

Få signerat utan att något e-postmeddelande skickas

En portal som visar ceremonin hemma behöver ofta inte vår inbjudan: den kommer tillsammans med deras egen resa och erbjuder ett konto till en kund som inte vill ha det. Ange värdet NONE för meddelandekanalens inställning för en mottagare och ingenting skickas längre till dem — du tar dem till sin signering.

  • • Inställningen är per mottagare, inte per kuvert: du kan tysta ned kunden du är värd för och behålla e-posten för en extern motunderskrivare, som inte har någon portal.
  • • Det är reserverat för signerare och godkännare, de enda som du har en länk att överlämna till. Du läser den från svaret på skapande och sändning, eller du begär en ny URL vid klick på POST /api/v1/envelopes/{id}/embed-url.
  • • Automatiska påminnelser slutar av sig själva för denna mottagare: vi skrev aldrig till dem, vi börjar inte med en påminnelse. Övriga mottagare fortsätter att påminnas normalt.
  • • Signeringscertifikatet nämner det, mottagare för mottagare. En bevisfil som skulle tiga om detta skulle få det att verka som om denna undertecknare mottog från oss en inbjudan som aldrig existerade.
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.

Visa ditt kundens namn som avsändare

Som standard läser undertecknaren namnet på API-nyckelns ägare. Om du låter flera företag underteckna dokument med en enda nyckel skickar du sender-fältet när du skapar kuvertet: signeringssidan och e-postmeddelanden om inbjudan och påminnelse visar sedan det berörda företagets namn.

  • • Reserverat för Business-planen och högre. I en lägre plan nekas skapandet istället för att låta undertecknaren läsa ett annat namn än det förväntade.
  • • Namnet är en visning: certifikatet och granskningsspåret behåller den verkliga avsändaren, och e-postmeddelanden skickas alltid från Certyneo.
  • • Adressen är valfri. Utan den ser undertecknaren bara namnet, aldrig API-nyckelns ägares adress.
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"
  }
}

Autentisering

Varje anrop bär en API-nyckel i Authorization-huvudet. Nycklar genereras från Inställningar → API-nycklar och visas bara en gång.

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_… i produktion, sk_test_… för sandbox. Rubrik: Authorization: Bearer <clé>.
  • • Omfång: envelopes, documents, webhooks, seals — i läsning (:read) eller skrivning (:write). Skrivning medför läsning; omfånget * ger alla rättigheter.
  • • Nycklarna sk_test_ skapar resurser i sandlådan, exkluderade från kvoten och faktureringen. Inget riktigt e-postmeddelande skickas till mottagaren, om inte dennes adress matchar det sändande kontots e-post — användbart för att testa hela flödet på dig själv.
  • • Fel: 401 ogiltig nyckel, 403 otillräckligt omfång, 429 gräns för datahastighet överskriden, 402 månatlig kvot nådd.

Formulär för svar

En sak att känna till innan du skriver din klient: samlingar är inkapslade i ett data-objekt, medan enskilda resurser returneras platt. Att läsa response.data.data på en enskild resurs returnerar därför undefined.

Samling — innehållsfylldjson
// GET /api/v1/envelopes
// Collections are WRAPPED in a "data" array.
{
  "data": [
    { "id": "env_abc123", "subject": "Contrat", "status": "SENT" }
  ]
}
Enhetlig resurs — flätadjson
// GET /api/v1/envelopes/{id}
// Single resources are returned FLAT — no "data" envelope.
{
  "id": "env_abc123",
  "subject": "Contrat",
  "status": "COMPLETED",
  "recipients": [ /* … */ ]
}

Hastighetsgränser

Gränserna garanterar stabil servicekvalitet för alla kunder. Om du behöver mer, kontakta oss.

  • • 100 förfrågningar per minut per API-nyckel
  • • Burst tolererat upp till 200 förfrågningar på mindre än 10 sekunder
  • • 429-svar med Retry-After-rubrik som anger fördröjningen i sekunder

Gå längre