Download OpenAPI specification:
Webhooks are a real-time communication method between systems. OviPro supports webhooks to notify partner systems of resource changes.
Webhook usage is as follows: The client registers a webhook endpoint URL using the Subscription API. The client should securely store the secret signature key from subscription creation. Once the subscription is created, OviPro will start sending requests to the client's webhook endpoint.
The Subscription API POST endpoint returns a Base64 encoded signatureSigningKey. It is a string of 64 characters. This key is used to sign and verify event payloads. The client should store this key securely.
Webhook requests are sent using HTTP POST with a JSON payload. The payload is a CloudEvents envelope containing the event data. This standard defines a simple base structure for events. See the CloudEvents specification for more details if interested.
Webhook requests from OviPro contain a signature header called X-OviPro-Signature,
which is calculated using a shared private secret key. The listener can verify the
request payload using the same calculation and comparing this against the signature.
The signature contains a timestamp part and a hash part. The client should verify
that the timestamp is within a reasonable time frame (e.g. 5 minutes) for added security.
Signature parts are separated with a , character. The current hash part scheme is v1.
Timestamp is Finnish standard time in epoch milliseconds.
Signature header format:
X-OviPro-Signature: t=1739953479406,v1=16720e3e956efb2fa9bd339ea6d02346529b7943e3e181a184c0afc68d00d78f
The hash is calculated using HMAC with SHA-256 algorithm. HMAC input message consists of the epoch
timestamp and the request payload as strings with a . separator. Hex representation of this result
is used. Currently at v1, multiple versions of the hash calculation may be included. The latest
version should be used.
Example calculation and verification:
const payload = '{"id":"ac723003-e881-4e97-b231-ac041b653b6c",...';
const secret = 'drjjZQ19DA/KQdUbnF+...';
const signatureHeaderValue = 't=1739953479406,v1=16720e3e956efb2fa9bd339ea6d023465...';
const [, timestamp] = signatureHeaderValue.split(',')[0].split('=');
const [, signatureHashValue] = signatureHeaderValue.split(',')[1].split('v1=');
const signaturePayload = `${timestamp}.${payload}`;
const expectedSignatureHashValue = crypto.createHmac('sha256', secret)
.update(signaturePayload).digest('hex');
crypto.timingSafeEqual(new Uint8Array(Buffer.from(expectedSignatureHashValue)),
new Uint8Array(Buffer.from(signatureHashValue)));
The webhook endpoint should be reachable and respond with a 2xx status code. Event delivery will be disabled if an endpoint fails to respond in time or fails multiple times. The client can re-enable the event by updating the subscription.
If you have any questions, comments or feedback regarding our APIs, please contact developer@ovipro.fi.
Validate the webhook endpoint sending an OPTIONS request. See https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/http-webhook.md#41-validation-request. This is sent when the subscription is set to enabled state on creation or on update. The server may decide to throttle or drop requests if the endpoint is not reachable and has not been validated.
| WebHook-Request-Origin required | string Example: api.ovipro.fi The origin of the webhook request. This header is used to verify the request origin. |
Notify the client of entity updates.
| X-OviPro-Signature required | string Example: t=1739953479406,v1=16720e3e956efb2fa9bd339ea6d02346529b7943e3e181a184c0afc68d00d78f Signature header for verifying the request payload integrity. See the Webhook Payload Verification. |
| Authorization required | string Example: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... The authorization token for the request. |
Describes the event data.
| id required | string <uuid> The event ID. Combined with |
| source required | string The source context of the event. |
| specversion required | string Value: "1.0" The version of the CloudEvents specification. |
| type required | string (EventType) [ 1 .. 100 ] characters Enum: "fi.ovipro.assignment.assignment_activated" "fi.ovipro.digital_trade.completed" "fi.ovipro.digital_trade.signing_can_be_started" "fi.ovipro.purchase_offer.offer_accepted" The event type identifier. |
| recordedtime required | string <date-time> The time the event was attributed to sending it. |
| time | string <date-time> The time of occurrence of the event. See also |
required | purchaseOfferAccepted (object) or assignmentActivated (object) or digitalTradeSigningCanBeStarted (object) or digitalTradeCompleted (object) The event data. |
{- "id": "123e4567-e89b-12d3-a456-426614174000",
- "source": "/webhook-api-v1",
- "specversion": "1.0",
- "type": "fi.ovipro.assignment.assignment_activated",
- "recordedtime": "2021-10-01T12:00:00Z",
- "time": "2021-10-01T12:00:00Z",
- "data": {
- "subscriptionId": "123e4567-e89b-12d3-a456-426614174000",
- "entityId": "123e4567-e89b-12d3-a456-426614174000",
- "entityType": "PURCHASE_OFFER"
}
}