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.
Ö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]=198501019876" \
-F "recipients[0][email]=anna@example.se" \
-F "recipients[0][role]=signer"Ta emot en webhook när mottagaren signerar
Konfigurera en webhook-URL (görs av MySign åt er) 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 MB 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. Används för uppslag och i webhook-payloads. |
methods | valfri | Kommalista: EID (BankID), PHONE (SMS-kod), DRAWN (handskriven). Standard: EID. |
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. |
recipients[n][name] | obligatorisk | Minst en mottagare krävs. Se mottagarfält för fullständig lista. |
attachments[n] | valfri | Kompletterande PDF:er som bifogas dokumentet. Max 20 bilagor, sammanlagt 50 MB; 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]=198501019876" \
-F "recipients[0][email]=anna@example.se" \
-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][role]=signer" \
-F "recipients[1][invitationOrder]=2" \
-F "attachments[0]=@stadgar.pdf;type=application/pdf"Svar — 201 Created
{
"success": true,
"document": {
"id": "1HBR5TuZb",
"status": "PENDING",
"externalReference": "member-4711",
"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:
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,
"document": {
"id": "1HBR5TuZb",
"documentName": "Medlemsavtal 2026",
"externalReference": "member-4711",
"status": "COMPLETED",
"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",
"invitationOrder": 1
}
]
}
}status är ett av: DRAFT, PENDING, COMPLETED, DECLINED, EXPIRED, CANCELLED. Varje mottagares status: PENDING, OPENED, REVIEWED, SIGNED, DECLINED.
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.
Kontrollerar att nyckeln fungerar och svarar med företaget den tillhör (company.name, company.organizationNumber). Använd den som anslutningstest.
Prenumererar en URL på händelser, utöver företagets egen webhook-URL. Skicka JSON med url (https) och valfritt events — en lista med händelsenamn; utelämnad betyder alla. 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, i exakt samma form som en webhook-leverans — avsett som exempeldata när ni bygger ett flöde. Finns ingen sådan händelse ännu returneras en exempelhändelse.
Mottagare & signeringsmetoder
05| Fält | Krav | Beskrivning |
|---|---|---|
name | obligatorisk | Mottagarens namn. |
email | obligatorisk | Används för inbjudan när deliveryMethod är email. |
idNumber | villkorad | Personnummer. Se Personnummer & BankID — obligatoriskt i vissa fall. |
phone | villkorad | Krävs om deliveryMethod=sms eller signeringsmetoden är PHONE. |
role | valfri | signer (standard) eller reviewer. |
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. Webhook-URL:en konfigureras tillsammans med er API-nyckel — hör av er med den URL ni vill ta emot anrop på.
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
Åtta 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"
}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"
}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.
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.
Varje (dokument, mottagare, händelsetyp)-kombination levereras som mest en gång per faktisk statusändring — men bygg mottagaren idempotent ändå (nyckla på documentId + recipientId + event) som skydd mot dubbletter om nätverket lurar er.
Felkoder
07Alla fel svarar { "success": false, "error": "…", "code": "…" }.
| 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. |
| 400 | NO_RECIPIENTS | Minst en mottagare krävs. |
| 400 | INVALID_DEADLINE | deadline är inte ett heltal ≥ 0. |
| 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 MB. |
| 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 MB. |
| 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. |
| 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 finns inte — se Händelser. |
| 429 | RATE_LIMITED | För många anrop. 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 saknar en aktiv ägare att tillskriva dokumentet — kontakta MySign. |
| 500 | INTERNAL_ERROR | Oväntat serverfel. Säkert att försöka igen. |
Gränser
Varje nyckel får göra 600 läsanrop och 60 skrivanrop (skapa ärende, prenumerera/avprenumerera) per minut. Över gränsen svarar API:et 429 Too Many Requests med koden RATE_LIMITED och headern Retry-After (sekunder).
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 MB per PDF. | |
Sidor | 1–250 sidor. | |
Bilagor | Max 20 st, sammanlagt 50 MB. | |
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
08API:et är versionerat via /v1/-prefixet; brytande ändringar landar i en ny version.
- Nya endpoints: testa nyckeln, prenumerera på händelser och senaste händelser.
- Hastighetsbegränsning per nyckel — se Gränser.
- Webhook-payloaden innehåller nu även
documentName.
- Uppladdade PDF:er valideras (storlek, sidantal, bilagor, aktivt innehåll) med nya felkoder. Öppningsåtgärder som bara styr startvyn tillåts — se Gränser och Felkoder.
deadlinehar standardvärde 30 dagar. Tidigare gav ett utelämnat värde ett dokument som redan hade gått ut. Ogiltiga värden gerINVALID_DEADLINE.- Dokument får nu status
EXPIREDochdocument.expiredskickas när deadlinen passerat — det uteblev tidigare. - Oväntade fel svarar alltid med
INTERNAL_ERRORoch utan interna feldetaljer.
Första utgåvan: skapa signeringsärende, hämta status (via ID eller externalReference), hämta signerad PDF, samt webhooks för samtliga dokument- och mottagarstatusövergångar.