Tidvis
Utviklere · Enterprise

Tidvis Sign Public API

REST API v1 og webhooks for å bygge egne integrasjoner mot Tidvis Sign. OAuth2 client credentials, signerte webhooks og fullt avtaleløp.

Hurtigstart

Base URL: https://tidvis.se/api/public/v1. Alle kall bruker JSON. Public API er del av Enterprise-planen.

  1. 1. Opprett en API-klient under Sign → Innstillinger → API og lagre client_id og client_secret.
  2. 2. Bytt dem mot et access_token via OAuth2 client credentials.
  3. 3. Opprett en avtale, last opp en PDF, legg til deltakere og send.
curl -X POST https://tidvis.se/api/public/v1/oauth/access-token \
  -H "Content-Type: application/json" \
  -d '{"client_id":"tvc_...","client_secret":"tvs_..."}'

Én modell — API og plattform er samme avtale

Avtaler opprettet via API-et ligger i samme tabell og deler hele infrastrukturen med avtaler opprettet i web-UI-et:

  • Vises direkte i plattformen under fanen Via integration i /app/sign/dokument.
  • Kan åpnes, patches, purres og avbrytes både via API og i UI-et.
  • Inngår i samme auto-påminnelses-cron, arkiv og 18-måneders retensjon som native-avtaler.
  • Signeringslenken er alltid https://tidvis.se/sign/<token> — samme flyt som avtaler laget i plattformen.
  • UI viser en Via {external_source}-badge (klikkbar når external_url er satt) så admin kan hoppe tilbake til CRM-posten.
  • Send med sender i requesten så autosigneres avsenderen ved send — samme oppførsel som plattform-UI:et.

Autentisering

OAuth2 client credentials. Bytt client_id+client_secret mot en JWT som er gyldig i 1 time. Send Authorization: Bearer <access_token> på alle påfølgende kall.

POST/oauth/access-token

Hent et access token (1t TTL).

{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "expires_at": "2026-06-07T13:00:00.000Z"
}
DELETE/oauth/access-token

Tilbakekall gjeldende token (krever Authorization-header).

Avtaler

POST/agreements

Opprett et avtaleutkast (status: draft).

curl -X POST https://tidvis.se/api/public/v1/agreements \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title":"Arbeidsavtale Anna","expires_in_days":14,"bankid_required":true}'
GET/agreements

List avtaler. Støtter ?status, ?limit, ?cursor.

GET/agreements/:id

Hent en avtale med deltakere og status. Også status-pollingendepunktet — se under.

GET/agreements/:id/events

Audit-spor (sent, viewed, signed, completed...).

GET/agreements/:id/download

Hent signert PDF (returnerer signed URL eller binært innhold).

Poll signeringsstatus

Tidvis Sign har ingen egen /status-ressurs — GET /agreements/:id er pollingendepunktet. Responsen inneholder avtalens status samt participants[].status og signed_at per part, så du kan vise f.eks. "1 av 2 har signert" i ditt eget UI uten å vente på webhook.

Anbefaling: bruk webhooks (agreement.viewed, agreement.signed, agreement.completed) som primær kanal og fall tilbake på polling hvert 30. sekund når webhook ikke er et alternativ. Avtalestatus kan være draft, sent, partially_signed, completed, declined eller cancelled.

# Poll status og tell signerte
curl -s https://tidvis.se/api/public/v1/agreements/$ID \
  -H "Authorization: Bearer $TOKEN" \
  | jq '{
      status,
      signed: ([.participants[] | select(.status == "signed")] | length),
      total: (.participants | length),
      participants: [.participants[] | {name, email, status, signed_at}]
    }'

Eksempel-svar (1 av 2 signert):

{
  "status": "partially_signed",
  "signed": 1,
  "total": 2,
  "participants": [
    { "name": "Anna Andersson", "email": "anna@example.com", "status": "signed",  "signed_at": "2026-06-17T09:14:22Z" },
    { "name": "Erik Eriksson",  "email": "erik@example.com",  "status": "viewed",  "signed_at": null }
  ]
}

Deltakere

POST/agreements/:id/participants

Legg til en signatar (kun i draft-tilstand).

{
  "name": "Anna Andersson",
  "email": "anna@example.com",
  "role": "signer",
  "job_title": "Daglig leder",
  "phone": "+4791234567",
  "personal_id_masked": "19800101-XXXX",
  "notifications_enabled": true
}
POST/agreements/:id/participants/:pid/decline

Avvis avtalet for en bestemt deltaker. Setter avtalets status til 'declined'.

{ "reason": "Vilkårene er ikke akseptable" }
POST/agreements/:id/participants/:pid/delegate

Delegér signering til en ny person. Den opprinnelige deltakeren merkes 'delegated'.

{
  "name": "Erik Eriksson",
  "email": "erik@example.com",
  "job_title": "Finansdirektør",
  "phone": "+4790123456",
  "message": "Henviser til Erik som håndterer signering."
}
PATCH/agreements/:id/participants/:pid/notifications

Slå av/på påminnelses-e-poster for en enkelt deltaker.

{ "enabled": false }
GET/agreements/:id/chat

List chat-meldinger mellom agenten og deltakerne på en avtale.

POST/agreements/:id/chat

Send en chat-melding. Angi participant_id for å videreformidle en melding fra en deltaker. Utløser webhooken agreement.chat_message.

{
  "body": "Hei, kan dere se gjennom vedlegg 2?",
  "sender_label": "Tidvis Sign Agent",
  "participant_id": "8a3..."
}

PDF-dokumenter

PUT/agreements/:id/documents/main

Last opp hoveddokumentet. Støtter application/pdf (binært) eller JSON med base64.

# JSON / base64
curl -X PUT https://tidvis.se/api/public/v1/agreements/$ID/documents/main \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"filename":"avtale.pdf","content_base64":"JVBERi0..."}'

# Eller binært
curl -X PUT https://tidvis.se/api/public/v1/agreements/$ID/documents/main \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/pdf" \
  --data-binary @avtale.pdf

Livssyklus

POST/agreements/:id/lifecycle

Send eller avbryt en avtale.

{"action": "send"}   // eller "cancel"

BankID

Du kan kreve svensk BankID-signering per avtale. Sett bankid_required: true ved opprettelse (eller via PATCH før sending). Når avtalen sendes signerer hver deltaker med BankID på mobil eller desktop i stedet for å tegne sin signatur.

Krav

  • Kontoen må ha planen Sign Pro og tillegget BankID aktivert.
  • Pris: 100 BankID-signaturer inkludert per måned, deretter 5 SEK/signatur.
  • Uten tillegget returnerer POST /agreements/:id/lifecycle med action: "send" feilen 402 bankid_disabled.

Opprett BankID-avtale

curl -X POST https://tidvis.se/api/public/v1/agreements \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Arbeidsavtale Anna",
    "bankid_required": true
  }'

Svar (forkortet):

{
  "id": "agr_...",
  "status": "draft",
  "bankid_required": true,
  "document": { "uploaded": false, "sha256": null },
  "participants": []
}

Webhook-payload når BankID brukes

For avtaler med bankid_required: true berikes agreement.signed-hendelsen med en signature-blokk. Av personvernhensyn eksponeres verken personnummer, sertifikater eller OCSP-svar via API-et eller webhooks.

{
  "event": "agreement.signed",
  "agreement_id": "agr_...",
  "participant": { "id": "p_...", "email": "anna@example.com" },
  "signature": {
    "method": "bankid",
    "signer_name": "Anna Andersson",
    "signed_at": "2026-06-11T08:42:11.000Z"
  }
}

Feltet signature.method er alltid en av "otp_email" eller "bankid". Avtaler med blandede deltakere logger metoden per signatar.

BankID-identifisering før åpning

Eget tillegg som tvinger mottakeren til å legitimere seg med BankID før dokumentet vises. Det er en gate foran selve PDF-en og er uavhengig av valgt signaturmetode — du kan altså kreve BankID-legitimering og fortsatt la signeringen skje med engangskode på e-post, klikk-signatur eller tegnet signatur. Kombineres gjerne med bankid_required: true når du vil ha både identifisering før åpning og BankID-signering ved undertegning.

Slå på ved opprettelse

curl -X POST https://tidvis.se/api/public/v1/agreements \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "NDA Anna",
    "bankid_identify_required": true
  }'

Svar (forkortet):

{
  "id": "agr_...",
  "status": "draft",
  "bankid_required": false,
  "bankid_identify_required": true,
  "participants": []
}

Atferd for mottakeren

  • Når mottakeren åpner lenken vises en BankID-gate i stedet for PDF-en.
  • Mottakeren må starte BankID på mobil eller via QR-kode og bekrefte legitimeringen.
  • Først deretter åpnes PDF-en og valgt signaturmetode blir aktiv.
  • "viewed"-hendelsen logges etter legitimeringen, ikke ved første klikk på lenken.

Krav og pris

  • Kontoen må ha Sign Pro og tillegget BankID aktivert — samme krav som bankid_required.
  • Identifiseringer teller ikke mot BankID-kvoten på 100 signeringer/mnd. Kun faktiske BankID-signeringer (bankid_required: true) debiteres 5 SEK/stk ut over inkluderte.
  • Uten tillegget returnerer POST /agreements/:id/lifecycle med action: "send" feilen 402 bankid_disabled.

Webhook-payload

En egen hendelse agreement.identified sendes når en mottaker har legitimert seg. Personnummer, sertifikater og OCSP-svar eksponeres aldri via API-et.

{
  "event": "agreement.identified",
  "agreement_id": "agr_...",
  "participant": { "id": "p_...", "email": "anna@example.com" },
  "identification": {
    "method": "bankid",
    "signer_name": "Anna Andersson",
    "identified_at": "2026-06-12T10:21:04.000Z"
  }
}

Avtalegenerator

Bygg en AI-drevet avtalemal fra 2–10 eksempelavtaler og generer deretter nye avtaler med ett kall. Genererte avtaler kan lastes ned som DOCX ellersendes direkte til signering via Sign — i så fall får du tilbake en sign_document_id.

Krav & pris

  • Avtalemodulen må være aktiv (99 SEK/bruker/måned). Ellers returneres 402 plan_required.
  • MCP/agent-kall koster 3 SEK per generering i tillegg til modulprisen.
  • Kildefiler maks 20 MB per fil, 2–10 filer per mal (PDF eller DOCX).

Scopes

  • templates:read — list og hent maler
  • templates:manage — opprett og slett maler
  • generations:create — generer nye avtaler fra mal
  • generations:read — list, hent og last ned genererte avtaler
  • Hvis signature_method: "bankid" brukes i generate, kreves også agreements:send.
GET/agreement-templates

List lagrede avtalemaler.

POST/agreement-templates

Opprett mal fra 2–10 eksempelavtaler. Multipart (files[]) eller JSON med base64 (sources[]).

curl -X POST https://tidvis.se/api/public/v1/agreement-templates \
  -H "Authorization: Bearer $TOKEN" \
  -F "name=Konsulentavtale" \
  -F "files=@eksempel1.pdf" \
  -F "files=@eksempel2.pdf" \
  -F "files=@eksempel3.docx"
GET/agreement-templates/:id

Hent et malskjema (felter, blokker, kilder).

DELETE/agreement-templates/:id

Slett en mal permanent.

POST/agreement-templates/:id/generate

Generer ny avtale fra mal. Returnerer DOCX inline (default) eller et sendt Sign-utkast når send_for_signing=true og recipients er oppgitt.

{
  "values": {
    "kunde_navn": "Acme AS",
    "belop": 45000,
    "startdato": "2026-08-01"
  },
  "send_for_signing": true,
  "signature_method": "bankid",
  "recipients": [
    { "name": "Anna Andersen", "email": "anna@acme.no" }
  ]
}
GET/agreement-generations?template_id=...

List genererte avtaler (filtrer valgfritt på template_id).

GET/agreement-generations/:id

Hent metadata om en generering.

GET/agreement-generations/:id/download

Signert nedlastings-URL (gyldig 10 min) til generert PDF/DOCX.

Fullstendige request/response-skjemaer finnes i OpenAPI-referansen.

Webhooks

Tidvis leverer hendelser til din URL via POST JSON. Hvert kall er signert med HMAC-SHA256 i headeren X-Tidvis-Signature: sha256=<hex> basert på din signing_secret og raw body. Mislykkede leveranser forsøkes på nytt med eksponentiell backoff i opptil 24t.

POST/webhooks

Registrer en webhook.

{
  "client_id": "<api_client uuid>",
  "url": "https://din-app.no/webhooks/tidvis",
  "events": ["agreement.sent","agreement.signed","agreement.completed"]
}
GET/webhooks

List registrerte webhooks.

DELETE/webhooks/:id

Slett en webhook.

Hendelser

  • agreement.sent
  • agreement.viewed
  • agreement.signed
  • agreement.completed
  • agreement.cancelled
  • agreement.declined
  • agreement.delegated
  • participant.notifications_changed
  • agreement.chat_message
  • agreement.expired
  • agreement.identified

For avtaler med bankid_required: true inkluderer agreement.signed/agreement.completed også en signature-blokk. Se BankID.

Verifiser signatur (Node.js)

import { createHmac, timingSafeEqual } from "node:crypto";

function verify(rawBody, header, secret) {
  const expected = createHmac("sha256", secret).update(rawBody).digest("hex");
  const given = (header || "").replace(/^sha256=/, "");
  return timingSafeEqual(Buffer.from(expected), Buffer.from(given));
}

Feilkoder

HTTPCodeBetydning
400invalid_requestFeil input.
401unauthorizedMangler/ugyldig token.
402plan_requiredKontoen mangler Enterprise-plan. Inkluderer upgrade_url.
402bankid_disabledAvtalen har bankid_required: true men kontoen mangler BankID-tillegget.
403forbiddenMangler rettigheter til ressursen.
404not_foundRessursen ble ikke funnet.
409conflictUgyldig tilstandsovergang (f.eks. sende allerede sendt avtale).
429rate_limitedFor mange kall.
500server_errorServerfeil – prøv igjen.

Rate-grenser

Standardgrense: 60 kall/minutt per klient og 600/time for opplastinger. Ved overskridelse får du 429 rate_limited med Retry-After-header. Trenger du mer? Kontakt oss.

MCP & AI-agenter

Tidvis Sign eksponerer en Model Context Protocol-server slik at AI-agenter (ChatGPT, Claude Desktop, egne agenter) kan opprette, sende og spore avtaler med ett enkelt verktøykall. Discovery-manifest finnes på /.well-known/mcp.json. En dedikert landingsside ligger på /no/utviklere/mcp.

Endepunkt

POST https://tidvis.se/api/mcp
Authorization: Bearer <access_token>
Content-Type: application/json
Accept: application/json, text/event-stream

Scopes

API-tokens kan begrenses til spesifikke scopes. For MCP kreves mcp:connect + valgfri kombinasjon av:

  • agreements:read – hent avtaler & events
  • agreements:create – opprett utkast & deltakere
  • agreements:send – send avtaler til signering
  • agreements:cancel – avbryt avtaler
  • billing:checkout – generer checkout-lenke
  • templates:read / templates:manage – håndter avtalemaler
  • generations:create / generations:read – generer & les avtaler fra mal
  • mcp:connect – kreves for MCP-tilgang

Tilgjengelige verktøy

  • tidvis_sign_create_agreement
  • tidvis_sign_add_participant
  • tidvis_sign_upload_pdf
  • tidvis_sign_send_agreement
  • tidvis_sign_cancel_agreement
  • tidvis_sign_get_agreement
  • tidvis_sign_list_events
  • tidvis_sign_create_checkout
  • tidvis_sign_decline_agreement
  • tidvis_sign_delegate_signing
  • tidvis_sign_set_participant_notifications
  • tidvis_sign_list_chat_messages
  • tidvis_sign_post_chat_message
  • tidvis_sign_list_agreement_templates
  • tidvis_sign_get_agreement_template
  • tidvis_sign_create_agreement_template
  • tidvis_sign_generate_agreement
  • tidvis_sign_list_agreement_generations
  • tidvis_sign_get_agreement_generation

Claude Desktop-konfigurasjon

{
  "mcpServers": {
    "tidvis-sign": {
      "url": "https://tidvis.se/api/mcp",
      "headers": { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
    }
  }
}

Agent-checkout & betal-per-avtale

To måter en agent kan la sluttkunden betale:

  • Sign Pro (abonnement) – månedsavgift per sete, ubegrenset antall avtaler. Bruk tidvis_sign_create_checkout med product: "sign_pro_monthly" og ønsket antall seter.
  • Betal per avtale – 19 SEK/avtale som forhåndsbetalte kreditter, perfekt for lavvolums-agenter. Bruk product: "sign_per_agreement" og antall kreditter (1–500). Kreditter trekkes automatisk når send_agreement kjøres på free-plan-kontoer.

Checkout-verktøyet returnerer en Stripe-hostet URL som agenten viser til sluttkunden. Ved 402 plan_requiredsend_agreement mangler kontoen både kreditter og Sign Pro – svaret inneholder en upgrade_url agenten kan lenke til.

Klar til å se Tidvis?

Bestill en uforpliktende demo. Vi viser systemet tilpasset din virksomhet, uten salgspress.