Developer Handbook
Partner API
Skicka ett färdigt PDF-avtal till MySign, låt mottagaren signera med BankID, SMS-kod eller handskriven signatur, och hämta det signerade dokumentet tillbaka — via ett REST-API byggt på samma flöde som MySigns eget signeringsgränssnitt.
Kontakta MySign för en API-nyckelÖversikt
01Partner-API:et täcker sträckan från ett färdigt PDF-dokument till en signerad, arkiverad kopia: ladda upp filen, lägg till en eller flera mottagare, låt MySign sköta inbjudan och signeringen, och hämta resultatet — själva signeringsupplevelsen (BankID-appen, SMS-koden, den ritade signaturen) sker fortfarande på MySigns egen hostade signeringssida, som mottagaren når via en länk i mejlet eller SMS:et.
Varje ärende kan taggas med en externalReference — ert eget medlems- eller avtals-ID — så att ni kan korrelera ett MySign-dokument med er egen post utan att behöva spara MySigns interna ID separat.
Mappar och grupper (dashboardens sätt att organisera dokument) exponeras medvetet inte här — de är interna organisationsbegrepp utan motsvarighet i en partnerintegration.
Snabbstart
02Skaffa en API-nyckel
Kontakta MySign för att få en API-nyckel utfärdad till ert företag. Nyckeln visas i klartext en gång — spara den direkt i er secrets-hantering, den går inte att se igen.
Skapa ett signeringsärende
Skicka PDF:en och mottagaren i ett anrop. Dokumentet skickas till mottagaren omedelbart.
curl -X POST https://mysign.se/api/partner/v1/documents \
-H "Authorization: Bearer msk_live_xxxxxxxxxxxxxxxxxxxx" \
-F "documentName=Medlemsavtal 2026" \
-F "externalReference=member-4711" \
-F "methods=EID" \
-F "file=@avtal.pdf;type=application/pdf" \
-F "recipients[0][name]=Anna Andersson" \
-F "recipients[0][idNumber]=198501019874" \
-F "recipients[0][email]=anna@example.se" \
-F "recipients[0][role]=signer"Ta emot en webhook när mottagaren signerar
Konfigurera en webhook-URL (en ägare gör det själv under Integrationer > API & webhook) och lyssna på document.completed — se Webhooks. Ni kan även lyssna på recipient.viewed/.signed för delstatus under tiden.
Hämta den signerade PDF:en
curl https://mysign.se/api/partner/v1/documents/1HBR5TuZb/pdf \
-H "Authorization: Bearer msk_live_xxxxxxxxxxxxxxxxxxxx" \
-o medlemsavtal-signerat.pdfAutentisering
03Varje anrop autentiseras med en API-nyckel i Authorization-headern:
Authorization: Bearer msk_live_<nyckel>Nyckeln är knuten till ert företag i MySign — alla dokument som skapas med den tillhör automatiskt er organisation, och alla status-/PDF-anrop är begränsade till era egna dokument. Ett anrop utan giltig nyckel, eller med en återkallad nyckel, svarar 401 Unauthorized med koden INVALID_API_KEY.
Behandla nyckeln som en hemlighet — den har full åtkomst till att skapa dokument, läsa status och hämta signerade PDF:er i ert namn. Om den läcker, be MySign återkalla den och utfärda en ny.
Endpoints
04Laddar upp ett PDF-dokument, skapar signeringsärendet och skickar inbjudan till den första mottagargruppen omedelbart. multipart/form-data.
Fält
| Fält | Krav | Beskrivning |
|---|---|---|
documentName | obligatorisk | Dokumentets namn, visas för mottagaren. |
file | obligatorisk | Det färdigrenderade PDF-dokumentet. Filnamnet måste sluta på .pdf. Max 20 MiB (20 971 520 byte) och 250 sidor. Krypterade/lösenordsskyddade PDF:er och PDF:er med aktivt innehåll avvisas — se Gränser. |
externalReference | valfri | Ert eget medlems-/avtals-ID. Sätts en gång, ändras aldrig. Behöver inte vara unikt. Används för uppslag och i webhook-payloads. |
methods | valfri | Kommalista: EID (BankID), PHONE (SMS-kod), DRAWN (handskriven). Mellanslag runt värdena, versaler/gemener och dubbletter spelar ingen roll. Utelämnad eller tom: EID. Ett annat värde avvisas med 400 INVALID_SIGNATURE_METHOD (details.invalid listar dem). Med PHONE måste varje undertecknare ha ett mobilnummer. |
deadline | valfri | Antal dagar som dokumentet går att signera, som heltal. Standard: 30 (samma som i MySigns dashboard) — gäller även om ni skickar 0. Ett värde som inte är ett heltal ≥ 0 avvisas med 400 INVALID_DEADLINE. |
redirectUrl | valfri | En https-adress som en part skickas vidare till efter att ha signerat, godkänt, avböjt eller (som godkännare) begärt ändring. Adressens domän måste vara registrerad av en ägare i MySign i förväg, och adressen kan inte ändras efter att dokumentet skickats. Max 2 000 tecken, utan fragment (#). Se Omdirigering efter signering. |
recipients[n][name] | obligatorisk | Minst en mottagare krävs, och varje mottagare måste ha ett namn. Se mottagarfält för fullständig lista. |
attachments[n] | valfri | Kompletterande PDF:er som bifogas dokumentet. Max 20 bilagor, sammanlagt 50 MiB; varje bilaga valideras som file. |
obligatoriskmåste skickas med·villkoradkrävs bara i vissa fall·valfrikan utelämnas
Fullständigt exempel med två mottagare i signeringsordning:
curl -X POST https://mysign.se/api/partner/v1/documents \
-H "Authorization: Bearer msk_live_xxxxxxxxxxxxxxxxxxxx" \
-F "documentName=Medlemsavtal 2026" \
-F "externalReference=member-4711" \
-F "methods=EID,PHONE" \
-F "deadline=14" \
-F "file=@avtal.pdf;type=application/pdf" \
-F "recipients[0][name]=Anna Andersson" \
-F "recipients[0][idNumber]=198501019874" \
-F "recipients[0][email]=anna@example.se" \
-F "recipients[0][phone]=+46701234567" \
-F "recipients[0][role]=signer" \
-F "recipients[0][invitationOrder]=1" \
-F "recipients[1][name]=Klubbens kassör" \
-F "recipients[1][email]=kassor@golfklubben.se" \
-F "recipients[1][phone]=+46707654321" \
-F "recipients[1][role]=signer" \
-F "recipients[1][invitationOrder]=2" \
-F "attachments[0]=@stadgar.pdf;type=application/pdf"Svar — 201 Created
{
"success": true,
"livemode": true,
"document": {
"id": "1HBR5TuZb",
"status": "PENDING",
"externalReference": "member-4711",
"redirectUrl": "https://app.example.se/avtal/tack",
"createdAt": "2026-09-15T12:50:39.587Z"
},
"invitationDelivery": {
"attempted": 1,
"sent": 1,
"failed": 0,
"failures": []
}
}invitationDelivery kan i sällsynta fall vara null — ärendet är då skapat men leveransresultatet kunde inte rapporteras. Följ ärendet via statusendpointen som vanligt.
Hämtar status för ett ärende, inklusive varje mottagares delstatus.
Sök på MySigns ID (returnerat vid skapandet), eller på er egen externalReference via query-parametern — praktiskt om ni bara sparar er egen referens. Referensen behöver inte vara unik: delar flera dokument samma referens returneras det senast skapade av dem, bland nyckelns företags dokument i nyckelns läge (live eller test).
curl "https://mysign.se/api/partner/v1/documents/lookup?externalReference=member-4711" \
-H "Authorization: Bearer msk_live_xxxxxxxxxxxxxxxxxxxx"(externalReference tar alltid företräde över {id} i sökvägen när den är angiven — vilket värde som helst, t.ex. lookup, fungerar då som platshållare.)
Svar — 200 OK
{
"success": true,
"livemode": true,
"document": {
"id": "1HBR5TuZb",
"documentName": "Medlemsavtal 2026",
"externalReference": "member-4711",
"redirectUrl": "https://app.example.se/avtal/tack",
"status": "COMPLETED",
"revisionInProgress": false,
"version": 1,
"sentAt": "2026-09-15T12:50:39.584Z",
"finalizedAt": "2026-09-15T13:11:33.580Z",
"cancelledAt": null,
"expiredAt": null,
"createdAt": "2026-09-15T12:50:39.587Z",
"recipients": [
{
"id": "y8gsm5YFt",
"name": "Anna Andersson",
"email": "anna@example.se",
"role": "signer",
"status": "SIGNED",
"signedAt": "2026-09-15T13:11:25.390Z",
"approvedAt": null,
"changeRequestedAt": null,
"invitationOrder": 1
}
]
}
}En mottagares status är PENDING, OPENED, REVIEWED (har läst hela), SIGNED, APPROVED, CHANGES_REQUESTED eller DECLINED. En mottagare är klar när en signer är SIGNED, en approver är APPROVED och en reviewer är REVIEWED (eller SIGNED). revisionInProgress och version beskrivs under nya versioner.
status är ett av: DRAFT, PENDING, COMPLETED, DECLINED, EXPIRED, CANCELLED. Varje mottagares status: PENDING, OPENED, REVIEWED, SIGNED, APPROVED, CHANGES_REQUESTED, DECLINED. CHANGES_REQUESTED gäller bara en godkännare; en undertecknare eller läsare som begär ändring behåller sin status här. livemode är true för en live-nyckel och false för en testnyckel.
Strömmar den signerade PDF:en (application/pdf) när ärendet är COMPLETED.
curl https://mysign.se/api/partner/v1/documents/1HBR5TuZb/pdf \
-H "Authorization: Bearer msk_live_xxxxxxxxxxxxxxxxxxxx" \
-o medlemsavtal-signerat.pdfAnropas innan dokumentet är klart svarar det 409 Conflict med koden NOT_COMPLETED — vänta på document.completed-webhooken eller polla statusendpointen istället för att gissa på en timing. Svaret innehåller dokumentets aktuella status i fältet status.
Kontrollerar att nyckeln fungerar och svarar med företaget den tillhör (company.name, company.organizationNumber) och med livemode — true för en live-nyckel, false för en testnyckel. Använd den som anslutningstest.
Prenumererar en URL på händelser, utöver företagets egen webhook-URL. Skicka JSON med url (https, max 2 000 tecken) och valfritt events — en lista med högst 20 händelsenamn; utelämnad eller tom betyder alla. En body som inte klarar detta avvisas med 400 INVALID_INPUT, och error säger vad som är fel. Svaret innehåller prenumerationens id och en secret som visas endast här och signerar varje leverans på samma sätt som under Verifiera signatur.
curl -X POST https://mysign.se/api/partner/v1/webhooks \
-H "Authorization: Bearer msk_live_<nyckel>" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/hooks/mysign","events":["document.completed"]}'Avsluta med DELETE /api/partner/v1/webhooks/{id}. En mottagare som svarar 410 Gone på en leverans avprenumereras automatiskt.
Returnerar företagets senaste händelser av en typ, nyast först, i samma form som en webhook-leverans — avsett som exempeldata när ni bygger ett flöde. Svaret är { "success": true, "events": [...] } med högst tre händelser, en per dokument (och mottagare för mottagarhändelser). Varje händelse har dessutom ett id, <documentId>:<recipientId>:<type> (tomt recipientId för dokumenthändelser). Finns ingen sådan händelse ännu returneras en exempelhändelse, som saknar livemode. Endast händelser i nyckelns läge (live eller test) visas. Saknas type eller är den okänd svarar API:et 400 UNKNOWN_EVENT.
Mottagare & signeringsmetoder
05| Fält | Krav | Beskrivning |
|---|---|---|
name | obligatorisk | Mottagarens namn. Får inte vara tomt (mellanslag räknas inte), annars 400 MISSING_REQUIRED_FIELDS med de berörda mottagarna i details.offendingRecipients. |
email | villkorad | Krävs, och måste vara en giltig adress, när deliveryMethod är email (standard) — inbjudan skickas dit. Valfri vid sms, men en adress som anges måste vara giltig. Annars 400 INVALID_EMAIL. |
idNumber | villkorad | Personnummer. Se Personnummer & BankID — obligatoriskt i vissa fall. |
phone | villkorad | Mobilnummer. Krävs när deliveryMethod=sms (annars 400 SMS_RECIPIENT_MISSING_PHONE), och för varje undertecknare när methods innehåller PHONE (annars 400 MISSING_PHONE); godkännare och läsare behöver inget nummer för PHONE. Ett användbart nummer är, efter att mellanslag, parenteser och bindestreck tagits bort, 7–15 siffror med valfritt inledande +, t.ex. +46701234567. |
role | valfri | signer (standard, undertecknare), approver (godkännare: läser och godkänner med en knapp utan att signera) eller reviewer (läsare: behöver bara läsa dokumentet). Minst en mottagare måste vara signer, annars avvisas anropet med NO_SIGNER. |
deliveryMethod | valfri | email (standard) eller sms — hur inbjudan skickas, oberoende av signeringsmetod. |
invitationOrder | valfri | Heltal, standard 1. Mottagare med samma tal bjuds in samtidigt; en högre grupp bjuds in först när alla i en lägre grupp är klara — praktiskt för "medlem signerar, sedan klubbens kassör". |
requireBankIdToView | valfri | "true"/"false". Kräver BankID-identifiering innan mottagaren ens kan öppna dokumentet (utöver själva signeringen). |
obligatoriskmåste skickas med·villkoradkrävs bara i vissa fall·valfrikan utelämnas
Signeringsmetoder (methods)
| Värde | Beskrivning | |
|---|---|---|
EID | BankID — svensk e-legitimation för stark autentisering och registrering av mottagarens godkännande. MySigns PDF-sigill är separat och tillhör plattformen. | |
PHONE | SMS-kod — 6-siffrig engångskod skickad via SMS, 10 minuters giltighet. | |
DRAWN | Handskriven — signatur ritad med finger/mus i signeringsgränssnittet. |
Personnummer & BankID
Personnummer valideras mot svenskt format (ÅÅÅÅMMDD-NNNN eller ÅÅMMDD-NNNN, bindestreck valfritt) med Luhn-kontrollsiffra. Ett värde som skickas med men inte klarar valideringen avvisas med 400 INVALID_PERSONAL_ID.
idNumber kan lämnas tomt även när methods innehåller EID — MySign fångar då upp personnumret direkt från BankID-legitimeringen vid signeringstillfället. Om ni redan känner till mottagarens personnummer, skicka det ändå: det verifieras mot BankID-svaret vid signering, så en signering av fel person avvisas.
Undantaget är requireBankIdToView=true — då krävs personnumret redan vid skapandet (400 MISSING_PERSONAL_ID annars), eftersom identitetskontrollen sker innan dokumentet ens visas.
Webhooks
06MySign postar en signerad JSON-payload till en URL ni tillhandahåller varje gång ett dokument eller en mottagare byter status. En ägare eller administratör anger webhook-URL:en och ser hemligheten i MySign under Integrationer > API & webhook. Hemligheten visas bara när den skapas.
Verifiera signaturen
Varje leverans innehåller en X-MySign-Signature-header: sha256=<hex-HMAC>, beräknad över den råa request-bodyn med er webhook-hemlighet. Verifiera innan ni litar på innehållet. Händelsetypen skickas även i X-MySign-Event-headern, praktiskt för routing innan bodyn parsas:
const crypto = require("crypto");
function verifyMySignSignature(rawBody, signatureHeader, secret) {
const expected =
"sha256=" +
crypto.createHmac("sha256", secret).update(rawBody, "utf8").digest("hex");
// timing-safe jämförelse
return crypto.timingSafeEqual(
Buffer.from(signatureHeader),
Buffer.from(expected),
);
}
// I er route-handler, INNAN body:n parsas som JSON:
// const valid = verifyMySignSignature(rawBody, req.headers["x-mysign-signature"], WEBHOOK_SECRET);
// if (!valid) return res.status(401).end();Beräkna HMAC:en över den råa, oparsade request-bodyn — inte över ett omserialiserat JSON-objekt. De flesta ramverk måste explicit be om raw body för webhook-routes (t.ex. express.raw()) innan JSON-parsern annars konsumerar den.
Händelser
Tretton händelsetyper i två grupper — dokumentnivå (hela ärendet) och mottagarnivå (en enskild mottagares framsteg, oberoende av om övriga mottagare är klara).
Dokumentnivå
Mottagarnivå — en per mottagare
Exempel — document.completed
{
"event": "document.completed",
"documentId": "1HBR5TuZb",
"externalReference": "member-4711",
"status": "COMPLETED",
"signedPdfUrl": "https://mysign.se/api/partner/v1/documents/1HBR5TuZb/pdf",
"occurredAt": "2026-09-15T13:11:33.580Z",
"timestamp": "2026-09-15T13:11:33.581Z",
"documentName": "Medlemsavtal 2026",
"livemode": true
}signedPdfUrl pekar på partner-API:et (kräver samma Authorization-header som alla andra anrop) — aldrig en bar lagringslänk. document.declined/.expired/.cancelled har samma form men saknar signedPdfUrl.
Exempel — recipient.signed
{
"event": "recipient.signed",
"documentId": "1HBR5TuZb",
"recipientId": "y8gsm5YFt",
"recipientName": "Anna Andersson",
"recipientEmail": "anna@example.se",
"externalReference": "member-4711",
"status": "SIGNED",
"occurredAt": "2026-09-15T13:11:25.390Z",
"timestamp": "2026-09-15T13:11:25.390Z",
"documentName": "Medlemsavtal 2026",
"livemode": true
}Ett dokument med flera mottagare skickar recipient.signed för varje mottagare allt eftersom de signerar, och document.completed separat, en gång, när den sista är klar. Anta inte att de är samma HTTP-anrop eller kommer i strikt ordning vid omförsök.
Nya versioner av ett skickat dokument
Avsändaren kan ändra ett dokument som redan är skickat genom att göra en ny version. Dokumentet behåller sitt documentId och sin externalReference, och dess status är PENDING hela vägen. Fältet version börjar på 1 och ökar med varje publicerad version, och revisionInProgress är true medan signeringen är pausad. Båda finns i händelserna nedan och i svaret från statusanropet.
Exempel — document.version_published
{
"event": "document.version_published",
"documentId": "1HBR5TuZb",
"externalReference": "member-4711",
"status": "PENDING",
"revisionInProgress": false,
"version": 2,
"changeNote": "Betalningsvillkoren i punkt 4 är ändrade till 30 dagar",
"changes": [
"Dokumentets innehåll har ändrats",
"Ny part: Bo Berg (godkännare)"
],
"occurredAt": "2026-09-16T09:02:11.120Z",
"timestamp": "2026-09-16T09:02:11.121Z",
"documentName": "Medlemsavtal 2026",
"livemode": true
}changeNote är avsändarens egen notering (kan vara null) och changes en lista med vad som skiljer från versionen innan, en rad per ändring. document.revision_started och .revision_cancelled har samma form utan de två fälten.
| Fält | Krav | Beskrivning |
|---|---|---|
livemode | obligatorisk | Finns i varje webhook-leverans (inte i exempelhändelsen från GET /events). true för ett riktigt dokument, false för ett testdokument (skapat med en testnyckel). Det är ett tillägg: inget annat fält har ändrats. Signaturen i X-MySign-Signature gäller hela den skickade texten och är oförändrad. Se Testläge. |
obligatoriskmåste skickas med·villkoradkrävs bara i vissa fall·valfrikan utelämnas
Efter document.version_published ska ni nollställa det ni sparat om mottagarnas signaturer och godkännanden för dokumentet. Mottagarhändelserna (recipient.viewed, .signed, .approved och de andra) skickas igen när mottagarna agerar på den nya versionen. Mottagare som finns kvar behåller sitt recipientId; en mottagare som tagits bort eller bytt e-postadress försvinner ur statusanropets lista, och en ny får ett nytt id.
Leverans & omförsök
Varje händelse levereras med POST, Content-Type: application/json, 5 sekunders timeout. Ett icke-2xx-svar (eller timeout) schemalägger ett omförsök med exponentiell backoff:
| Försök | Fördröjning | |
|---|---|---|
1 (direkt) | — | |
2 | 1 minut | |
3 | 5 minuter | |
4 | 30 minuter | |
5 | 2 timmar | |
6 (sista) | 6 timmar |
Omförsöken plockas upp av ett jobb som körs var femte minut, så fördröjningarna ovan är minimivärden — ett omförsök kan komma upp till fem minuter senare.
Efter sex försök ges leveransen upp permanent. Svara 2xx så fort ni har verifierat signaturen och sparat/köat händelsen — gör den faktiska bearbetningen asynkront istället för att låta MySigns 5-sekunders timeout styra hur lång tid er handler får ta.
En mottagarhändelse skickas som mest en gång per mottagare, händelsetyp och dokumentversion — recipient.changes_requested en gång per ändringsbegäran. document.version_published skickas en gång per version, document.revision_started och .revision_cancelled en gång per tillfälle (de kan alltså komma flera gånger för samma dokument), och övriga dokumenthändelser en gång per dokument.
Bygg ändå mottagaren idempotent, som skydd mot dubbletter om nätverket lurar er. En nyckel som fungerar för alla händelser är documentId + recipientId (tom för dokumenthändelser) + event + occurredAt. Ett omförsök skickar exakt samma body som första försöket.
Omdirigering efter signering
07Vill ni att en part ska hamna på er egen webbplats när hen är klar skickar ni med fältet redirectUrl när ärendet skapas. Med en live-nyckel returnerar MySign inga signeringslänkar: parterna får sin länk i MySigns eget e-post- eller SMS-utskick, och det är efter signeringen som de skickas vidare. (Testnycklar returnerar länkar, se Testläge.)
När det sker
Direkt efter att MySign har sparat partens val, för dessa utfall: signed (signerat), approved (godkänt), declined (avböjt) och changes_requested (begärt ändring, bara för en godkännare). Samma adress används för alla fyra; utfallet står i parametern mysign_status. En läsare (reviewer) skickas aldrig vidare, och inte heller en undertecknare eller läsare som begär ändring.
Det sker aldrig för en utgången, återkallad eller avbruten inbjudan, aldrig för en ogiltig eller redan använd länk, aldrig vid fel, och aldrig om signeringen behöver göras om. Om ni tar bort domänen i MySign efter att ärendet skickats skickas ingen vidare längre.
Vad parten ser
Parten skickas inte iväg direkt. En ruta säger att det är klart och att hen skickas vidare till er domän (domännamnet visas i klartext), med en nedräkning på fem sekunder, en knapp Fortsätt och en knapp Stanna kvar som avbryter omdirigeringen. Den som öppnar länken igen senare skickas aldrig vidare automatiskt. Omdirigeringen sker i samma flik; MySigns sida kan inte visas i en ram på er sida.
Omdirigeringen är en bekvämlighet för parten, inte ett bevis. En part kan stanna kvar, stänga fliken eller tappa nätet, och adressen kan öppnas av någon annan. Låt webhooks eller statusendpointen avgöra vad som är sant.
Registrera domäner
MySign skickar bara vidare till domäner som ert företag har registrerat i förväg. En ägare eller administratör lägger till dem under Inställningar > Integrationer > API & webhook. Att registrera example.se tillåter även underdomäner som app.example.se, men inte evilexample.se. Delade värdsuffix som github.io och vercel.app, och andranivåregister som co.uk, går inte att registrera som de är — registrera ert eget namn under dem (t.ex. example.co.uk).
Har företaget ingen webhook-hemlighet när en ägare eller administratör registrerar en domän skapar MySign en och visar den en gång, direkt där. Den används för att signera omdirigeringen, se Parametrar & signatur.
En API-nyckel kan inte registrera domäner, bara läsa listan (GET /api/partner/v1/redirect-domains). Det är avsiktligt: en nyckel som hamnar i fel händer ska inte kunna peka om era parter till en annan sida.
Adressen måste börja med https://, sakna användarnamn, port och fragment, och peka på ett domännamn (inte en IP-adress). Era egna query-parametrar får vara kvar, utom sådana som börjar med mysign_. Ett ärende med en adress som inte godkänns skapas inte — se felkoder redirect_* under Felkoder.
Parametrar & signatur
MySign lägger till följande parametrar på er adress. Inget om personen läggs till: inga namn, e-postadresser, telefonnummer, personnummer eller länkar.
| Parameter | Krav | Beskrivning |
|---|---|---|
mysign_document | obligatorisk | Dokumentets ID. |
mysign_reference | valfri | Er externalReference, om dokumentet har en. |
mysign_status | obligatorisk | signed, approved, declined eller changes_requested. |
mysign_ts | obligatorisk | Unix-tid i sekunder när adressen skapades. |
mysign_mode | obligatorisk | live eller test. Alltid med, och med i signaturen. test betyder ett testdokument (testnyckel). |
mysign_sig | obligatorisk | Hex-kodad HMAC-SHA256 över strängen nedan, med företagets webhook-hemlighet som nyckel. Varje omdirigering är signerad. |
obligatoriskmåste skickas med·villkoradkrävs bara i vissa fall·valfrikan utelämnas
https://app.example.se/avtal/tack?kampanj=var
&mysign_document=1HBR5TuZb
&mysign_reference=member-4711
&mysign_status=signed
&mysign_ts=1760446800
&mysign_mode=live
&mysign_sig=<64 hex-tecken>Det som signeras är exakt sex rader, sammanfogade med radbrytning (\n), i den här ordningen. Raden för referensen är tom om dokumentet saknar en:
mysign-redirect-v1
<mysign_document>
<mysign_reference, tom rad om den saknas>
<mysign_status>
<mysign_ts>
<mysign_mode>Använd värdena som de står i adressen (avkodade). Kontrollera signaturen på er server innan ni litar på parametrarna, och avvisa gamla tidsstämplar:
const crypto = require("crypto");
// query = parametrarna från adressen, redan avkodade
function verifyMySignRedirect(query, secret) {
const sig = query.mysign_sig;
if (!sig) return false; // utan signatur: lita inte på parametrarna
const canonical = [
"mysign-redirect-v1",
query.mysign_document,
query.mysign_reference ?? "",
query.mysign_status,
query.mysign_ts,
query.mysign_mode,
].join("\n");
const expected = crypto
.createHmac("sha256", secret)
.update(canonical, "utf8")
.digest("hex");
// Ett testdokument ska aldrig godtas i produktion.
if (query.mysign_mode !== "live") return false;
const fresh = Math.abs(Date.now() / 1000 - Number(query.mysign_ts)) < 600;
const a = Buffer.from(sig);
const b = Buffer.from(expected);
return fresh && a.length === b.length && crypto.timingSafeEqual(a, b);
}Avvisa mysign_mode=test i produktion. Läget ingår i signaturen, så en testomdirigering går inte att få att verifieras som live genom att byta parametern.
Nyckeln är företagets webhook-hemlighet, den som hör till kortet Webhook under Inställningar > Integrationer > API & webhook. Där kan den också bytas ut. Hemligheter för prenumerationer skapade med POST /api/partner/v1/webhooks signerar aldrig en omdirigering.
Testläge
08Med en testnyckel kan ni bygga och prova hela flödet utan att något skickas till riktiga personer och utan att något räknas mot er plan. Testnycklar har prefixet msk_test_… och skapas av en ägare eller administratör i MySign under Integrationer > API & webhook. Ni behöver samma aktiva prenumeration med API-åtkomst som för live-nycklar, och kan ha upp till 5 aktiva testnycklar per företag. Samma adress och samma endpoints används; det är nyckeln som avgör läget, aldrig en parameter i anropet.
Vad som skiljer
- Inget skickas ut. Varken e-post eller SMS går till mottagarna (inbjudningar, påminnelser, slutmejl). Mottagarna markeras ändå som inbjudna så att ordningen mellan grupper fungerar som vanligt.
- Signeringslänkar i svaret. Skapa-svaret och statussvaret innehåller
signingUrlper mottagare, så att ni själva kan öppna länken. Live-nycklar får aldrig några länkar. - Simulerade utfall. På signeringssidan finns en knapp för att simulera att parten signerar, godkänner, avböjer eller begär ändring, och motsvarande går att utlösa via API:et (se Simulera utfall). En simulerad BankID-signering är en tydligt märkt simulering utan personnummer.
- Vattenstämplat, inte giltigt. Det färdiga dokumentet bär en vattenstämpel och saknar organisationens sigill och tidsstämpel. Ett testdokument är inte ett giltigt signerat dokument och ska inte användas som ett.
- Webhooks med livemode. Varje händelse har
livemode: falseför testdokument ochlivemode: trueför riktiga. Er endpoint tar emot båda, så kontrollera fältet innan ni agerar. Omdirigeringen efter signering får också en markering för läget. - Rensas efter 30 dagar. Rensningen körs en gång per dygn, så ett testdokument tas bort inom ett dygn efter att det fyllt 30 dagar. Det går också att ta bort det tidigare i MySign.
- Max 100 testdokument. Företaget kan ha högst 100 testdokument åt gången. Över gränsen svarar API:et
test_document_limit(409) tills några har rensats eller tagits bort. - Läget är isolerat. En live-nyckel ser aldrig ett testdokument och en testnyckel ser aldrig ett riktigt: statusuppslag (på ID och
externalReference) och PDF-hämtning svarar404 NOT_FOUNDför dokument i fel läge, ochGET /eventsvisar bara händelser i nyckelns läge. Testdokument räknas inte i er dokumentkvot, i statistik eller i fakturering.
Fält i testläge
| Fält | Var | Beskrivning |
|---|---|---|
livemode | Finns i svaren från skapa, status, ping och simulera, och i varje webhook-leverans. true för en live-nyckel, false för en testnyckel. | |
document.recipients[n].signingUrl | Endast testnycklar, och bara medan ärendet är PENDING. Finns för varje mottagare som fortfarande kan agera: undertecknare och godkännare med status PENDING, OPENED, REVIEWED eller CHANGES_REQUESTED, läsare med PENDING, OPENED eller CHANGES_REQUESTED. Efter SIGNED, APPROVED eller DECLINED finns ingen länk. Gäller skapa-, status- och simulera-svaret. Länken är en fullständig adress och ni kan hämta en ny när som helst via statusendpointen. Live-nycklar får aldrig detta fält. |
Exempelsvar med testnyckel
{
"success": true,
"livemode": false,
"document": {
"id": "1HBR5TuZb",
"status": "PENDING",
"externalReference": "member-4711",
"redirectUrl": null,
"createdAt": "2026-10-14T12:50:39.587Z",
"recipients": [
{
"id": "cmg2x1k7a0001",
"name": "Anna Andersson",
"email": "anna@example.se",
"role": "signer",
"signingUrl": "https://mysign.se/d/p/1HBR5TuZb/<token>/"
}
]
},
"invitationDelivery": {
"attempted": 1,
"sent": 0,
"failed": 0,
"suppressed": 1,
"failures": []
}
}invitationDelivery visar sent: 0 i testläge: inget skickades. Skicka aldrig en testnyckel till en miljö som ska ha riktiga parter, och byt till en live-nyckel (msk_live_…) när ni är redo.
För en mottagare i ett testdokument till ett utfall, som om parten hade gjort det på signeringssidan. JSON-body.
| Fält | Krav | Beskrivning |
|---|---|---|
recipientId | obligatorisk | Mottagarens id från skapa- eller statussvaret. |
outcome | obligatorisk | signed eller declined för en undertecknare, approved eller changes_requested för en godkännare. En läsare har inget utfall att simulera. |
method | valfri | EID (standard), PHONE eller DRAWN. Gäller signed och måste vara en av dokumentets signeringsmetoder. |
message | valfri | Texten för changes_requested eller skälet för declined. Utelämnad får en standardtext. |
obligatoriskmåste skickas med·villkoradkrävs bara i vissa fall·valfrikan utelämnas
curl -X POST https://mysign.se/api/partner/v1/documents/1HBR5TuZb/simulate \
-H "Authorization: Bearer msk_test_<nyckel>" \
-H "Content-Type: application/json" \
-d '{"recipientId":"cmg2x1k7a0001","outcome":"signed","method":"EID"}'Svaret är detsamma som från statusendpointen (200), med det nya läget. Samma webhooks skickas som vid en riktig signering, med livemode: false. Ett anrop för ett utfall som mottagaren redan har ger samma svar och skickar inget igen.
Endast testnycklar: en live-nyckel får 403 test_mode_only. Ett utfall som inte hör till mottagarens roll ger 403 OUTCOME_ROLE_MISMATCH. Samma regler som på signeringssidan gäller i övrigt — signeringsordning, deadline, tillåtna metoder och att ärendet är PENDING — och bryter anropet mot en av dem svarar API:et med regelns kod, t.ex. 403 INVITATION_ORDER_LOCKED eller 403 SIGNATURE_METHOD_NOT_ALLOWED. Anropet räknas som ett skrivanrop i Gränser.
Felkoder
09Alla fel svarar { "success": false, "error": "…", "code": "…" }, även oväntade serverfel. Vissa fel har dessutom ett details-objekt med mer information, t.ex. details.offendingRecipients (vilka mottagare det gäller) eller details.invalid. Bygg på code, inte på texten i error.
| HTTP | Kod | Betydelse |
|---|---|---|
| 400 | INVALID_CONTENT_TYPE | Anropet var inte multipart/form-data, eller filens angivna typ är inte PDF. |
| 400 | INVALID_FORM_DATA | Formulärdatan kunde inte tolkas. |
| 400 | MISSING_REQUIRED_FIELDS | documentName eller file saknas, eller en mottagare saknar namn (details.offendingRecipients). |
| 400 | NO_RECIPIENTS | Minst en mottagare krävs. |
| 400 | INVALID_EMAIL | En mottagare som bjuds in via e-post saknar giltig adress, eller en angiven adress är ogiltig (details.offendingRecipients). |
| 400 | INVALID_DEADLINE | deadline är inte ett heltal ≥ 0. |
| 400 | INVALID_SIGNATURE_METHOD | methods innehåller något annat än EID, PHONE eller DRAWN (details.invalid). |
| 400 | INVALID_ROLE | En mottagares role är inte signer, approver eller reviewer. |
| 400 | NO_SIGNER | Ingen mottagare har rollen signer. Minst en måste signera. |
| 400 | SMS_RECIPIENT_MISSING_PHONE | En mottagare med deliveryMethod=sms saknar ett användbart mobilnummer (details.offendingRecipients). |
| 400 | MISSING_PHONE | methods innehåller PHONE men en undertecknare saknar ett användbart mobilnummer (details.offendingRecipients). |
| 409 | test_document_limit | Företaget har redan 100 testdokument. De rensas efter 30 dagar, eller så tar ni bort dem i MySign. Gäller bara testnycklar. |
| 400 | redirect_url_invalid | redirectUrl är ingen giltig absolut https-adress. |
| 400 | redirect_url_too_long | redirectUrl är längre än 2 000 tecken. |
| 400 | redirect_url_not_https | redirectUrl måste börja med https://. |
| 400 | redirect_url_credentials | redirectUrl får inte innehålla användarnamn eller lösenord. |
| 400 | redirect_url_port | redirectUrl får inte ange en port. |
| 400 | redirect_url_fragment | redirectUrl får inte innehålla ett fragment (#...). |
| 400 | redirect_url_reserved_parameter | redirectUrl använder en query-parameter som börjar med mysign_ — de lägger MySign till själv. |
| 400 | redirect_url_host_invalid | redirectUrl måste peka på ett publikt domännamn, inte en IP-adress eller ett internt namn. |
| 400 | redirect_domain_not_registered | redirectUrl:s domän är inte registrerad för ert företag. En ägare registrerar den i MySign (Inställningar > Integrationer > API & webhook). |
| 400 | INVALID_PERSONAL_ID | Ett angivet personnummer klarade inte formatvalideringen. |
| 400 | MISSING_PERSONAL_ID | Personnummer krävs (requireBankIdToView=true) men saknas. |
| 400 | EMPTY_FILE | Filen är tom. |
| 400 | FILE_TOO_LARGE | En PDF är större än 20 MiB (20 971 520 byte). |
| 400 | INVALID_FILE_EXTENSION | Filnamnet slutar inte på .pdf. |
| 400 | FILE_SIGNATURE_MISMATCH | Filens innehåll är inte en PDF, eller överföringen blev ofullständig. |
| 400 | PDF_MALFORMED | PDF:en är trasig eller ofullständig. |
| 400 | PDF_ENCRYPTED | Filen är lösenordsskyddad/krypterad. |
| 400 | PDF_PAGE_LIMIT_EXCEEDED | PDF:en har 0 eller fler än 250 sidor. |
| 400 | PDF_COMPLEXITY_LIMIT_EXCEEDED | PDF:en har fler än 50 000 interna objekt. |
| 400 | PDF_INVALID_PAGE_SIZE | En sida har ogiltig storlek (större än 14 400 pt eller noll). |
| 400 | PDF_UNSAFE_FEATURE | PDF:en innehåller aktivt innehåll, t.ex. JavaScript eller en öppningsåtgärd som gör mer än att visa en sida. details.feature anger vilket. |
| 400 | TOO_MANY_ATTACHMENTS | Fler än 20 bilagor. |
| 400 | ATTACHMENTS_TOO_LARGE | Bilagorna är sammanlagt större än 50 MiB. |
| 401 | INVALID_API_KEY | Saknad, ogiltig eller återkallad nyckel. |
| 403 | NO_ACTIVE_SUBSCRIPTION | Företaget saknar en aktiv MySign-prenumeration. |
| 403 | EMPLOYEE_LIMIT_EXCEEDED | Prenumerationens användargräns är överskriden. |
| 403 | DOCUMENT_LIMIT_REACHED | Prenumerationens dokumentgräns för perioden är nådd. |
| 404 | NOT_FOUND | Inget dokument matchade {id}/externalReference för ert företag. |
| 404 | SIGNED_PDF_MISSING | Dokumentet är klart men den signerade PDF:en saknas — kontakta MySign. |
| 409 | NOT_COMPLETED | PDF:en efterfrågades innan dokumentet är COMPLETED. Svaret har dokumentets aktuella status i fältet status. |
| 400 | INVALID_INPUT | Bodyn till POST /webhooks är inte ett JSON-objekt, url saknas eller är längre än 2 000 tecken, eller events är ingen lista med högst 20 händelsenamn. error säger vad. |
| 400 | INVALID_URL | Webhook-URL:en är ingen giltig adress. |
| 400 | HTTPS_REQUIRED | Webhook-URL:en måste börja med https://. |
| 400 | HOST_NOT_ALLOWED | Webhook-URL:en pekar på en IP-adress eller ett internt värdnamn. |
| 400 | UNKNOWN_EVENT | Händelsenamnet saknas eller finns inte (GET /events, POST /webhooks) — se Händelser. |
| 403 | test_mode_only | Simulera utfall anropades med en live-nyckel. Kräver en testnyckel. |
| 400 | INVALID_REQUEST | Simulera utfall: bodyn är inte JSON eller saknar recipientId. |
| 400 | INVALID_OUTCOME | Simulera utfall: outcome saknas eller är inte signed, declined, approved eller changes_requested. |
| 400 | INVALID_METHOD | Simulera utfall: method är inte EID, PHONE eller DRAWN. |
| 403 | OUTCOME_ROLE_MISMATCH | Simulera utfall: utfallet hör inte till mottagarens roll (signed/declined för signer, approved/changes_requested för approver). |
| 429 | RATE_LIMITED | För många anrop, eller för många ogiltiga nycklar från samma IP-adress. Vänta det antal sekunder som Retry-After anger. |
| 500 | UPLOAD_VERIFY_FAILED | Filuppladdningen kunde inte verifieras — försök igen. |
| 500 | NO_COMPANY_OWNER | Företaget har ingen kontaktperson och ingen aktiv användare att tillskriva dokumentet — kontakta MySign. |
| 500 | INTERNAL_ERROR | Oväntat serverfel. Försök igen; har ett skapa-anrop fått detta svar, kontrollera först med ett uppslag på externalReference att ärendet inte redan skapades. |
Gränser
Varje nyckel får göra 600 läsanrop och 60 skrivanrop (skapa ärende, prenumerera/avprenumerera, simulera utfall) per minut. Över gränsen svarar API:et 429 Too Many Requests med koden RATE_LIMITED och headrarna Retry-After (sekunder), X-RateLimit-Limit, X-RateLimit-Remaining och X-RateLimit-Reset (Unix-tid i sekunder när fönstret börjar om).
Misslyckade nyckelförsök räknas dessutom per IP-adress: efter 30 anrop med ogiltig nyckel (401) inom 60 sekunder får varje anrop från den adressen 429 RATE_LIMITED med Retry-After: 60, X-RateLimit-Limit: 30 och X-RateLimit-Remaining: 0 (ingen X-RateLimit-Reset), även med en giltig nyckel.
Dokumentskapande styrs dessutom av samma prenumerationsgränser som gäller för hela ert MySign-konto — antal dokument per period och antal användare — samma gräns som era kollegor som skapar dokument via dashboarden delar.
Varje uppladdad PDF (huvuddokument och bilagor) kontrolleras innan ärendet skapas:
| Gräns | Värde | |
|---|---|---|
Filstorlek | Max 20 MiB (20 971 520 byte) per PDF. | |
Sidor | 1–250 sidor. | |
Bilagor | Max 20 st, sammanlagt 50 MiB (52 428 800 byte). | |
Sidstorlek | Max 14 400 pt per sida och axel. | |
Komplexitet | Max 50 000 interna PDF-objekt. | |
Filnamn | Måste sluta på .pdf. | |
Aktivt innehåll | Avvisas: JavaScript, launch-åtgärder, rich media, inbäddade filer och händelsestyrda åtgärder (/AA). | |
Öppningsåtgärd | /OpenAction tillåts när den bara styr startvyn — en destination i dokumentet (sida, zoom) eller en GoTo dit. Allt annat (öppna en URL, skicka formulär, annan fil, JavaScript, kedjade åtgärder) avvisas. |
Ändringslogg
10API:et är versionerat via /v1/-prefixet; brytande ändringar landar i en ny version.
- v1.6Tydligare validering av mottagare och signeringsmetoder, signerade omdirigeringar alltid, och simulering av utfall i testläge — se Simulera utfall.
- v1.5Testläge med testnycklar — se Testläge.
- v1.4Omdirigering till er egen webbplats efter signering — se Omdirigering efter signering.
- v1.3Godkännare som mottagarroll och nya versioner av skickade dokument — se Händelser.
- v1.2Testa nyckeln, prenumerera på händelser, senaste händelser och hastighetsbegränsning — se Gränser.
- v1.1Validering av uppladdade PDF:er, standardvärde för deadline och status EXPIRED — se Felkoder.
- v1.0Första utgåvan: skapa signeringsärende, hämta status och signerad PDF, samt webhooks.