Visma Sign API v1

Introduction

Visma Sign is used for electronically signing documents like agreements, meeting minutes, powers of attorney, terms of service, etc.

Using Visma Sign, you can save up to 90% in the time and costs related to collecting signatures, compared to a paper process.

This API is used for automating the collection of electronic signatures.

Prerequisites

We will soon be providing a testing service which will not require an account at Visma Sign or a Finnish SSN / banking credentials.

Definitions

person
An end-user, identified by a nation-specific identifier, who can sign documents. Every person has their own document archive at Visma Sign.
organization
A person can have rights in multiple organizations. An organization has its own document archive at Visma Sign, and can add documents and invitations.
document
A top-level transaction, which includes files and will be signed by the invited parties. Considered signed and complete when all invitations have been fulfilled.
file
A document can currently include only one file, which must be a PDF and under 10MB. Information about collected signatures is written into the file itself.
invitation
A single requirement. Can specify a specific person who must fulfill it. Can specify notifications to be sent via email and/or sms.
signature
A fulfilled invitation. Always relates to one person. May contain a claim about representing an organization.

Common use cases

Immediately collect a signature from an end user

Examples:

  • User fills a form and immediately signs a document generated from the information. (request for proposal, order, ...)
  • Signing service ToS and confirming identity when registering a new user.

Flow:

  1. Create document and save the document uuid.
  2. Add file to be signed.
  3. Create invitations with messages disabled, save the invitation uuid.
  4. Obtain a list of authentication methods.
  5. Have user fulfill the invitation.
  6. Get document status and check it is signed.

Invite people to sign

Examples:

  • Customer service fills a form and invites someone to sign a document generated from the information.
  • After an immediately collected customer signature, customer service is invited to verify and sign a document.

Flow:

  1. Create document and save the document uuid.
  2. Add file to be signed.
  3. Create invitations.
  4. Wait until invitations have been fulfilled and poll document status if necessary.

Authentication

Your Visma Sign API credentials consist of a public client identifier (UUIDv4), and a secret key (32 bytes, delivered base64 encoded).

Organization level request authentication is done with a Amazon-style HMAC

Required headers

Content-MD5: base64(md5(body)), RFC 1864 (binary md5)
Content-Type: 'application/json'
Date: 'Mon, 07 Dec 2015 22:57:52 +0200' (RFC 2822)
Authorization: 'Onnistuu ' + client_identifier + ':' +
    base64(
      sha512_hmac( // returned as binary
        join(
          '\n', // unix newline, not the 2 character string
          [
            http_verb,    // 'POST' / 'GET' / etc.
            Content-MD5,  // Same as header above. Include even for empty string body.
            Content-Type, // Same as header above. Can be empty.
            Date,         // Same as header above.
            http_path     // '/api/v1/document/?foo=bar'
          ]
        ),
        key // in binary, remember to decode base64
      )
    )

Actions

Get invitation status

This action is public.

Request

GET /api/v1/invitation/2076243e-351d-4b29-86ad-c2b02d7f867d

Response

200 OK

{
    "uuid": "2076243e-351d-4b29-86ad-c2b02d7f867d",
    "status": "new",
    "document": {
        "name": "Test document"
    }
}

Returns 404 Not Found if the invitation was not found.

More information will be returned if the request is authenticated.

Response to an authenticated request:

200 OK

{
    "uuid": "2076243e-351d-4b29-86ad-c2b02d7f867d",
    "status": "new",
    "document": {
        "uuid": "e59c8dc8-8848-4936-ac7c-50d9ed72085a",
        "name": "Test document"
    }
}

The response may contain additional information.

Invitation statuses

waiting-for-send
The invitation has not been sent yet, and cannot be opened or fulfilled.
sending
The invitation messages are being sent. The invitation can be opened.
new
The invitation has been sent, and is waiting to be fulfilled.
opened
The invitation has been sent, is waiting to be fulfilled, and has been opened.
signed
The invitation has been fulfilled.
cancelled
The invitation and related transaction / document have been cancelled.

Get document status

This action requires authentication.

Request

GET /api/v1/document/e59c8dc8-8848-4936-ac7c-50d9ed72085a

Response

200 OK

{
    "uuid": "e59c8dc8-8848-4936-ac7c-50d9ed72085a",
    "name": "Test document",
    "status": "pending",
    "files": [
        {
            "filename": "0959d490-253c-4910-a818-e0f00e4abc97.pdf",
        }
    ],
    "invitations": [
        {
            "uuid": "2076243e-351d-4b29-86ad-c2b02d7f867d",
            "status": "new",
            "passphrase": "989c687b"
            "email": "petri.koivula+invitee@fraktio.fi",
            "sms": "+358408269139"
        }
    ]
}

Returns 404 Not Found if the document could not be found.

Document statuses

new
The document has been added to Visma Sign, but no invitations have been created for it.
pending
The document has unfulfilled invitations.
signed
All the invitations have been fulfilled and the document is complete.
deleted
The document was deleted before any invitations were created for it.
cancelled
The document and related invitations have been cancelled.

Get document file

In addition to this auhenticated action, the file can be fetched by using an invitation uuid and passphrase:

GET /api/v1/invitation/2076243e-351d-4b29-86ad-c2b02d7f867d/989c687b/files/0

This action requires authentication.

Request

GET /api/v1/document/e59c8dc8-8848-4936-ac7c-50d9ed72085a/files/0

Response

200 OK

<file content in body>

Returns 404 Not Found if the document could not be found or has no file attached.

Create document

To start a signing process, first create a document using this action, then add a file and create invitations.

This action requires authentication.

Request

POST /api/v1/document/

{
    "document": {
        "name": "Test document", // Required, 1-100 characters.
        "category_uuid": "0e4a431d-628d-49cb-b578-fe7e115f33d3", // Optional, must exist if defined
        "category": "Test category", // Optional, must exist if defined
        "invitations_valid_until": "2017-01-01", // Optional. After this day, if all invitations have not been fulfilled, the process is cancelled.
        "affiliates": [ // Optional. Most immediate affiliate first.
            {
                "code": "affiliate-123" // Required. Contact us for the values.
            },
            ...
        ]
    }
}

Response

201 Created

Location: https://www.onnistuu.fi/api/v1/document/e59c8dc8-8848-4936-ac7c-50d9ed72085a

Returns 404 Not Found if the document could not be found.

Validation error response

400 Bad Request

{
    "error": "Invalid document",
    "validation_errors": [
        {
            "path": "[document][name]",
            "error": "This value should not be blank."
        }
    ]
}

Add file to document

To start a signing process, first create a document, add a file using this action, and then create invitations.

Currently, only one file can be added. It must be a PDF and under 10MB in size.

This action requires authentication.

Request

POST /api/v1/document/e59c8dc8-8848-4936-ac7c-50d9ed72085a/files?...

Content-Type: application/pdf

<file content in body>

Request GET parameters

All of these are optional.

filename
Filename for the file.

Response

201 Created

Returns 404 Not Found if the document could not be found.

Validation error responses

400 Bad Request

{
    "error": "No file provided",
}
          
400 Bad Request

{
    "error": "Invalid filename",
    "validation_errors": [
        {
            "path": "",
            "error": "This value is too long. It should have 255 characters or less."
        }
    ]
}
        

Cancel a document

A document must have pending or unsent invites to be cancelled. All attached invites will be cancelled as well.

This action requires authentication.

Request

POST /api/v1/document/e59c8dc8-8848-4936-ac7c-50d9ed72085a/cancel

Response

200 OK

Returns 404 Not Found if the document could not be found isn't cancellable.

Delete a document

A document must be cancelled or signed or have no invitations or signatures to be deleted.

This action requires authentication.

Request

DELETE /api/v1/document/e59c8dc8-8848-4936-ac7c-50d9ed72085a

Response

200 OK

Returns 404 Not Found if the document could not be found or isn't deletable.

Create invitations for document

To start a signing process, first create a document, add a file, and then create invitations using this action.

This action requires authentication.

Request

POST /api/v1/document/e59c8dc8-8848-4936-ac7c-50d9ed72085a/invitations

[
    {
        "email": "petri.koivula+invitee@fraktio.fi", // Optional
        "identifier_type": "Finland_SSN", // Optional
        "identifier": "010101-123N", // Optional. Signature must match if specified.
        "sms": "+358408269139", // Optional
        "sign_as_organization": false, // Optional
        "language": "fi", // Optional. fi, sv, en
        "messages": { // Optional
            "send_invitation_email": true, // Optional
            "invitation_email_message": "An explanation of what you're invited to sign.", // Optional, up to 1000 characters
            "send_invitation_sms": true, // Optional
            "custom_sms": "You have been sent an invitation from Example Company in a separate message.", // Optional, 10-160 characters
            "separate_invite_parts": false, // Optional
            "send_invitee_all_collected_email": true, // Optional
            "send_inviter_one_collected_emails": true, // Optional
            "attachment_allowed": true // Optional
        },
        "inviter": { // Optional
            "name": "Example Company", // Optional, 5-50 characters
            "email": "petri.koivula+inviter@fraktio.fi", // Optional
            "logo": "https://www.onnistuu.fi/img/visma_sign.png" // Optional
        }
        "order": { // Optional
            "index": 1, // Optional
            "require_before_sending_next_invitations": false // Optional
        }
    },
    ...
]

Response

201 Created

[
    {
        "uuid": "2076243e-351d-4b29-86ad-c2b02d7f867d",
        "status": "waiting-for-send",
        "passphrase": "989c687b"
    },
    ...
]

Invitation messages are sent asynchronously soon after the invitations are created.

Invitations can be fulfilled by

  • using the Visma Sign signing ui, send user to https://www.onnistuu.fi/<language>/invitation/<uuid>/<passphrase>/
  • using you own ui and the fulfill action

Returns 404 Not Found if the document could not be found.

Validation error response

400 Bad Request

{
    "error": "Requirements invalid",
    "validation_errors": [
        {
            "path": "[0][email]",
            "error": "This value is not a valid email address."
        }
    ]
}

Get authentication methods

If you want to fulfill an invitation without showing a Visma Sign ui, you will need to provide the identifier of a valid method the user will be forwarded to for identification.

This action is public.

Request

GET /api/v1/auth/methods

Response

200 OK

{
    "methods": [
        {
            "identifier": "tupas-nordea",
            "name": "Nordea",
            "image": "https://www.onnistuu.fi/img/banks/nordea_button_70x70px.gif"
        },
        ...
    ]
}

Fulfill an invitation

This action can be used to fulfill an invitation without showing a Visma Sign ui.

Before using this action, you will need to know/collect the signers SSN and the authentication method they wish to use. The user must also be made aware of the content of the document they are signing.

The identifier / SSN of the person is required because Visma Sign only receives a hash of the identifier from the authentication provider.

This action requires authentication.

Request

POST /api/v1/invitation/2076243e-351d-4b29-86ad-c2b02d7f867d/signature

{
    "returnUrl": "https://example.org/fulfill-return/2076243e-351d-4b29-86ad-c2b02d7f867d", // Required. User will be returned to this url after signing.
    "identifier": "010101-123N", // Required. The SSN of the person who is signing.
    "authService": "tupas-nordea" // Required. The identifier of an authentication method.
}

Response

201 Created

Location: https://www.onnistuu.fi/fulfill?data=...&iv=...

Returns 404 Not Found if the invitation was not found or is in an incompatible state, or the options given are invalid.

The end user should be sent to the address given in the Location header to complete the process.

After signing, the end user will be redirected to the given returnUrl.

Search documents

This action requires authentication.

Request

GET /api/v1/document/?...

Request GET parameters

All of these are optional.

category
Filter by category UUID. Full match.
name
Filter by document name. Partial matches.
uuid
Filter by document UUID. Full match.
date_from
Filter by document creation date. YYYY-MM-DD, inclusive.
date_to
Filter by document creation date. YYYY-MM-DD, inclusive.
status
Filter by document status. Full match, status strings given in get document status
participant
Filter by invitee email, invitee phone number or signer name. Partial matches.
sort_by
Set sort field. Valid choices are "created_on" (default) and "name".
sort_order
Set sort order. Valid choices are "DESC" and "ASC". Defaults to newest first / alphabetical.
offset
Response is paged. Start at this document number.

Response

200 OK

{
    "total": 78,
    "offset": 0,
    "length": 20,
    "documents": [
        ... documents like in get document status
    ]
}

Get categories

This action requires authentication.

Request

GET /api/v1/category/

Response

200 OK

{
    "categories": [
        {
            "uuid": null,
            "name": "Root",
            "description": "Root category"
        },
        {
            "uuid": "0e4a431d-628d-49cb-b578-fe7e115f33d3",
            "name": "Test category",
            "description": "For testing Visma Sign"
        },
        ...
    ]
}

Get invitee groups

This action requires authentication.

Request

GET /api/v1/invitee-group/

Response

200 OK

{
    "invitee_groups": [
        {
            "uuid": "c27b9389-9a3a-4277-871d-48889bf83246",
            "name": "Group 1",
            "entries": [
                {
                    "uuid": "ae08108d-48a9-4a8e-811a-39a54641b257",
                    "email_address": "petri.koivula+invitee1@fraktio.fi",
                    "msisdn": null
                },
                {
                    "uuid": "b71d5ea9-b3f5-421f-a407-67d3eb3d60be",
                    "email_address": "petri.koivula+invitee2@fraktio.fi",
                    "msisdn": null
                }
            ]
        }
    ]
}

Get saved email messages

This action requires authentication.

Request

GET /api/v1/saved-invitation-message/email/

Response

200 OK

{
    "email_messages": [
        {
            "uuid": "ab6a9797-f3b8-49e3-82f5-fbd30ffd5c72",
            "title": "Example message",
            "message": "Example of a message to include in invitation emails.",
            "edited_on": "2016-11-30 13:14:34",
            "edited_by": "Petri Koivula"
        }
    ]
}

Get saved sms messages

This action requires authentication.

Request

GET /api/v1/saved-invitation-message/sms/

Response

200 OK

{
    "sms_messages": [
        {
            "uuid": "68752520-b671-11e6-996e-0242ac130003",
            "message": "Example SMS message.",
            "edited_on": "2016-11-30 13:14:50",
            "edited_by": "Petri Koivula"
        }
    ]
}

Frequently Asked Questions

Which countries is Visma Sign available in?

Finland.

How can I test against this API, manually or automated?

Unfortunately, the only public instance of this API is currently the production environment. You will need a Finnish SSN and authentication credentials from a bank or other provider.

We are working on providing a testing service which will not require an account at Visma Sign or a Finnish SSN / banking credentials. The testing service will also allow for automated testing.

I have noticed a bug / have a feature suggestion

Please contact us

Change log

2017-02-28
Added option for controlling whether the file can be attached to emails.
2017-02-22
Document cancel and delete implemented.
2017-02-16
Added filename GET parameter for document files.
2017-02-03
Validation and authentication clarifications.
2016-12-20
Added document search, category list, invitee group list and saved invitation messages actions.
2016-11-25
This API, v1, released. API v0 documentation is also available.