FastSign API Documentation

Webhooks

The FastSign API has support for webhooks. With webhooks, the FastSign platform tells your application about interesting events, instead of your application issuing API requests on an interval, checking for updated data.

The part of your application "listening" for events is called a webhook consumer. FastSign is a webhook provider.

Supported events

At this time, the following events are issued by the FastSign platform:

The events contract.signed and contract.rejected are mutually exclusive. That means only one of each event can ever be emitted for each contract. For example, if contract.rejected once has been emitted, a contract.signed will never happen for the same contract.

There is no possibility to only subscribe for a selected range of events. All types of events till be sent to your webhook consumer.

How to set up your consumer

FastSign provides two different mechanism for registering webhook consumers; via the API; and by logging in to the FastSign platform as customer admin.

Set up a consumer via the API

Prerequisite: Having a customer API token. A partner API token can't create consumers.

Send an API request to /api/webhooks according to the API documentation. The url field is required.

The response to your request will contain two important fields: public_key and key_id. Store these, as they are required when validating each webhook event sent to your consumer!

Set up a consumer via the portal

  1. Log in to the FastSign portal as a customer admin.
  2. Navigate to the API page in top menu.
  3. Click the Webhooks link.
  4. Click the Ny webhook button.
  5. Fill in the required URL field and submit the form.
  6. You will be presented the page Redigera webhook. Please store the values presented in the fields Publik nyckel and Key-ID. They are required when validating each webhook event sent to your consumer!

The webhook journey

  1. An event occurs inside the FastSign platform. FastSign creates webhook events with a payload containing the event type and a unique identifier of the originating resource. See payload examples.
  2. The webhook event is put in a queue waiting to be sent, which normally happens after a couple of seconds.
  3. FastSign creates a signed HTTP request using the IETF RFC 9421 standard. The request is signed with a private key which together with the public key you got when registering the consumer creates a key pair.
  4. The signed HTTP request is sent to the consumer URL. FastSign expects to get a response back within 10 seconds.
  5. The consumer handles the HTTP request by validating the signature. If the signature validation fails, stop further processing and return HTTP status code 400. If the consumer successfully handled the webhook event the response should have a 200 HTTP status code. If the consumer is occupied with other tasks, a 429 status code can be returned instead and FastSign will retry the event at later time.
  6. If the consumer could validate the signature of the HTTP request, it can continue reacting upon the event. One probable first step is to send an API request to FastSign to the URL in the data.id event payload key.

Payload examples

Code samples

{
   "type": "contract.signed",
   "timestamp": "2026-04-05 13:37:42",
   "data": {
      "id": "/api/contracts/366478"
   }
}

A webhook payload is the entire body of an HTTP request sent from FastSign to a webhook consumer. The payload is always in JSON format with the three root keys type, timestamp and data.

The value of type is one of the strings seen in the list under previous headline "Supported events".

The value of timestamp is a string with the date and time when the event occurred in the FastSign platform in the Europe/Stockholm timezone. The format of the timestamp is an ISO 8601 date, followed by a space and then an ISO 8601 time with hours, minutes and seconds.

The value of data is an object with an id key. The id value is meant to be used to create an API request to get the full resource data the event was about.

Security features

Code samples

POST /your-consumer-url HTTP/1.1
Host: your-application.example.com
Date: Thu, 02 Apr 2026 21:03:19 GMT
Content-Digest: sha-256=:h+BmbUkuPKwVB7h+S/Q1MTd62s0D6AYRGc8GvNEHeiw=:
Signature-Input: sig1=("@method" "@path" "host" "date" "content-digest");keyid="ed25519-1";alg="ed25519";created=1775163799;expires=1775163829
Signature: sig1=:ZCJfhBFYCzLQ9wWgtKo9+XtKpji2KSYhdxgY33XWaGKit5aBKgpN6k9JXRt9faK/I9Xh4WGWR6ffxbifnHObCA==:
Content-Type: application/json

{"type":"contract.rejected","timestamp":"2026-04-02 22:57:56","data":{"id":"\/api\/contracts\/68"}}

The code sample shows how an HTTP request looks like as seen by a webhook consumer. It contains three security features which must be validated together:

We strongly recommend that you use a library for your programming language for validating the signature. A curated list of such libraries can be found at httpsig.org website. For the PHP language, we recommend the Composer package macgirvin/http-message-signer.

You can also do a GitHub search for RFC 9421 and filter by your programming language.

Make sure that your selected library has support for the ED25519 algorithm.

Example of validating an event

Code samples

<?php declare(strict_types=1);

use HttpSignature\HttpMessageSigner;
use Nyholm\Psr7Server\ServerRequestCreator;
use Nyholm\Psr7\Factory\Psr17Factory;

// Step 1: Create a PSR-7 request object
$psr17_factory = new Psr17Factory();

$creator = new ServerRequestCreator(
    $psr17_factory,
    $psr17_factory,
    $psr17_factory,
    $psr17_factory,
);

$request = $creator->fromGlobals();

// Step 2: Configuration
// The public key and key ID is created for you when registering the consumer with FastSign
$public_key = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAltyTaOMgdu4SgBvY691THCFlCqgyWfXzm/GhF4fc39w=\n-----END PUBLIC KEY-----";
$key_id = 'ed25519-1';

// Step 3: Validation of signature
$verifier = (new HttpMessageSigner())
	->setPublicKey($public_key)
	->setKeyId($key_id)
;
$is_valid = $verifier->verifyRequest($request);

// Step 4: Handle validation result
if (!$is_valid) {
	// Not valid, stop further processing!
	http_response_code(400);
	exit();
}

// The webhook event has a valid signature, continue processing the event here.
$body = (string) $request->getBody();
$event = json_decode($body, true, 2, JSON_THROW_ON_ERROR);

This is a sample implementation of a webhook consumer in PHP using the recommended Composer package macgirvin/http-message-signer.

Step 1: Create a PSR-7 request object

As this library uses the PSR-7 standard for HTTP messages, the sample begins with constructing a request object from the PHP super globals ($_SERVER, $_POST etc.) using the Composer package nyholm/psr7-server.

It's possible that your framework of choice already has a PSR-7 implementation, consult the documentation of your framework and search for PSR-7.

Step 2: Configuration

The message signer library needs two configuration values; the public key and the key ID. Both of these values are created when the consumer was registered in FastSign.

Step 3: Validation of signature

A signer object is created from the library using the configuration values from step 3.

Using the signer object, called $verifier here, we call it's verifyRequest() method using the $request from step 1 as only argument. The return value is stored in the $is_valid variable as a boolean.

Step 4: Handle validation result

The $is_valid variable from step 3 must be checked to see if the signature was valid or not. A value of true means the signature was valid.

In this example, we check if $is_valid is false and in that case stops the processing of event and sets the HTTP response code to 400.

Retries (temporary errors)

In some circumstances the sending of a webhook event can be retried by the FastSign platform:

An event will be retried following a time schedule:

Delay between each send Time since event occured
5 minutes 5 minutes
30 minutes 35 minutes
2 hours 2 hours, 35 minutes
5 hours 7 hours, 35 minutes
10 hours 17 hours, 35 minutes
14 hours 31 hours, 35 minutes
20 hours 51 hours, 35 minutes
Full stop 75 hours, 35 minutes

An event can also be retried manually from inside the event log, available from the same page as registering a consumer. All events are saved in the log for one month.

Permanent errors

If a consumer misbehaves, FastSign will disable it after 10 permanent errors.

The following counts as a permanent error:

A disabled consumer will not receive more webhook events until a customer admin logs in to the FastSign portal and enables the consumer again.

When a consumer is disabled, an e-mail will be sent to either the e-mail used to register the customer or to the special field contact_email available when registering a consumer. An example of usage for contact_email is when a technical contact needs to be notified about the webhook consumer instead of the customer admin.