Download OpenAPI specification:Download
Welcome to the Web Trust (WT) API documentation.
The versioning schema of these APIs is Semver-friendly.
Kopjra is an Italian legal tech company, ISO 27001 certified, working on the design and development of innovative and cost-effective trust services and electronic signatures. Our patented technology follows the ISO 27037 international digital forensic standard, which details the guidelines for identification, collection, acquisition and preservation of digital evidence.
Web Trust (WT) is a suite of API solutions for electronically signing documents, webpages, and data flows. The main scope of most of the solutions is to sign an interaction between two parties over the Internet using a proprietary and patented technology. Web Trust’s solutions cover six possible workflows respectively, each of which could be integrated into a company process:
The UI (User Interface) of our solutions was designed to be fully responsive, allowing a seamless experience both in desktop and mobile devices, using WebView and WKWebView components available on Android and iOS SDKs.
The following table will show the main differences (features, probative value, etc.) between each API solution introduced above:
We are also offering a complete SaaS solution based on our Document Simple Forensic API, Web Sign, for professionals and companies who need a ready to use DTM (Digital Transaction Management) platform.
WT offers a set of endpoints that allow you to interact with the system. These endpoints are hosted at the following URL: https://api.webtrust.kopjra.com/v1. The following documentation will guide you through the available endpoints and their functionalities.
Preceding a manual activation on our part the user may also have access to a DEMO environment hosted at https://api-demo.webtrust.kopjra.com. This environment is a mirror of the production one and it is meant to be used for testing purposes only. The data stored in the DEMO environment is not guaranteed to be persistent. DEMO is not activated by default, if you need access to it please contact our support team.
WT offers http basic authentication to allow access to its API. You can register new WT credentials at our developer portal.
WT expects for the credentials to be included in all API requests to the server in a header Authorization.
Using HTTP Basic authentication, the user authenticates to WT by providing a credential string within the Authorization header. This credential string is encoded using base64 and consists of the id and secret, generated at our developer portal, separated by :.
For example, if the id is my_id and the secret is my_secret, the credential string would be my_id:my_secret and the base64 encoding would be bXlfaWQ6bXlfc2VjcmV0. Therefore the header would be:
Authorization: Basic bXlfaWQ6bXlfc2VjcmV0
Note that using
curlor one of our clients you don't have to transform to base64 by yourself. It is enough to specifyid:secret.
basicSome special users will have the capacity to perform certain API calls as if they were made by another user, thus impersonating that other user. The impersonation capacity is rather powerful and it is given only to certain users directly by the system administrators. From now on we will call the user that is trying to impersonate another, the impersonator.
Impersonation takes place when the API call contains the following header (besides the Authorization one):
X-Impersonate-User: <externalUserId>
With the concept of impersonation the user can be distributed into two (not necessarily) exclusive layers: the users that can be impersonated and the users that can impersonate other users (impersonators). An impersonator generally manages its own users and has a way to identify them in his/her own systems, this identification is what we called the externalUserId and it is the one that has to be provided when impersonating.
This impersonation header will instruct WT to:
externalUserId identifies a user that can be impersonated by the impersonator that is making the API call.if there is no user corresponding to that
externalUserIdthen the system will automatically create one and will link it to the impersonator.
Archetypes describe the tags schema that a set of your interactions must adhere to, in order to be created. For example, if you want to split all of your interactions in 2 partitions (one for privacy policies and one for contracts), you can define two different archetypes. In the first one, you will specify all the meaningful tags for privacy policies (eg: an identifier of the signer and the version of your privacy policy) and in the second one you will specify all the meaningful tags for contracts (eg: an identifier of the signer, the version of the contract, and your company's associate that signed the contract on its behalf).
Later on, when you will create interactions, you should specify the relevant archetypeId in the body of the create request and the system will prevent you to create an interaction with a meaningful archetypeId if its associated tags do not respect the schema indicated in the archetype.
This API call allows you to create an archetype.
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
| Content-Type required | string Value: "application/json" |
Archetype creation object
| name | string The Archetype's given name |
| smsCustomMessage | string Text to replace the default SMS message sent for OTP verification. Whithin this text we can use the placeholder |
| fullNameSignatureFont | string Deprecated Default: "Caveat" Enum: "Caveat" "LeagueScript" "MrsSaintDelafield" "ShadowsIntoLight" "SueEllenFrancisco" "AlexBrush" "Allura" "DancingScriptVariableFont" "Parisienne" "Stalemate" Font to be used when signatureType is |
object The customisations you applied to a Signature resource. Every field is optional. | |
required | object An object representing the tags to be added to the resource. Note: tag names can only contain US-ASCII letters and/or numbers. You can specify as many tag names as you like. In future you will be able to specify a regular expression to validate the tag value as well. For now, only null is accepted as value. |
{- "name": "Archetype 1",
- "smsCustomMessage": "OTP: {{CODE}} - Enter the above code to sign your document",
- "fullNameSignatureFont": "LeagueScript",
- "signatureCustomisations": {
- "whitelabel": false,
- "fullNameSignatureFont": "LeagueScript",
- "signPage": {
- "title": "Accettazione termini di servizio",
- "showLogo": true
}, - "otpSmsPage": {
- "title": "Verifica numero di telefono di cellulare",
- "subtitle": "Ti preghiamo di inserire il codice di verifica che invieremo al tuo numero di telefono cellulare",
- "showLogo": true
}, - "outcomePage": {
- "title": "Firma conclusa con successo",
- "titleRejected": "Firma rifiutata",
- "subtitle": "La procedura di firma è avvenuta con successo",
- "subtitleRejected": "La procedura di firma è stata rifiutata",
- "showLogo": true,
- "customLink": {
- "title": "Clicca qui per ritornare alla pagina principale",
- "redirectInSecs": 5
}
}
}, - "mandatoryTags": {
- "anyTagName": null
}
}{- "id": 1,
- "name": "Archetype 1",
- "smsCustomMessage": "OTP: {{CODE}} - Enter the above code to sign your document",
- "smsCustomMessageModeratedOn": null,
- "fullNameSignatureFont": "LeagueScript",
- "signatureCustomisations": {
- "whitelabel": false,
- "fullNameSignatureFont": "LeagueScript",
- "signPage": {
- "title": "Accettazione termini di servizio",
- "showLogo": true
}, - "otpSmsPage": {
- "title": "Verifica numero di telefono di cellulare",
- "subtitle": "Ti preghiamo di inserire il codice di verifica che invieremo al tuo numero di telefono cellulare",
- "showLogo": true
}, - "outcomePage": {
- "title": "Firma conclusa con successo",
- "titleRejected": "Firma rifiutata",
- "subtitle": "La procedura di firma è avvenuta con successo",
- "subtitleRejected": "La procedura di firma è stata rifiutata",
- "showLogo": true,
- "customLink": {
- "title": "Clicca qui per ritornare alla pagina principale",
- "redirectInSecs": 5
}
}
}, - "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "mandatoryTags": {
- "anyTagName": null
}
}You can use this endpoint to get all of your Archetypes.
| top | integer [ 1 .. 25 ] Default: 5 The maximum number of object to be returned. |
| skip | integer >= 0 Default: 0 The number of results to be skipped starting from the first result. Used for pagination. |
| sortBy | string Example: sortBy=name,-createdAt A sorting criteria. It must be specified as comma separated list of terms, where each term can be:
For example a valid sorting criteria specification would be:
With this criteria you will get a list of interaction sorted by |
curl "{SERVER}/archetypes" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" # TODO: Replace id:secret with the proper credentials
[- {
- "id": 1,
- "name": "Archetype 1",
- "smsCustomMessage": "OTP: {{CODE}} - Enter the above code to sign your document",
- "smsCustomMessageModeratedOn": null,
- "fullNameSignatureFont": "LeagueScript",
- "signatureCustomisations": {
- "whitelabel": false,
- "fullNameSignatureFont": "LeagueScript",
- "signPage": {
- "title": "Accettazione termini di servizio",
- "showLogo": true
}, - "otpSmsPage": {
- "title": "Verifica numero di telefono di cellulare",
- "subtitle": "Ti preghiamo di inserire il codice di verifica che invieremo al tuo numero di telefono cellulare",
- "showLogo": true
}, - "outcomePage": {
- "title": "Firma conclusa con successo",
- "titleRejected": "Firma rifiutata",
- "subtitle": "La procedura di firma è avvenuta con successo",
- "subtitleRejected": "La procedura di firma è stata rifiutata",
- "showLogo": true,
- "customLink": {
- "title": "Clicca qui per ritornare alla pagina principale",
- "redirectInSecs": 5
}
}
}, - "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "mandatoryTags": {
- "anyTagName": null
}
}
]This endpoint retrieves a specific archetype.
| archetypeId required | number Example: 85 |
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
curl "{SERVER}/archetypes/85" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" // TODO: Replace id:secret with the proper credentials
{- "id": 1,
- "name": "Archetype 1",
- "smsCustomMessage": "OTP: {{CODE}} - Enter the above code to sign your document",
- "smsCustomMessageModeratedOn": null,
- "fullNameSignatureFont": "LeagueScript",
- "signatureCustomisations": {
- "whitelabel": false,
- "fullNameSignatureFont": "LeagueScript",
- "signPage": {
- "title": "Accettazione termini di servizio",
- "showLogo": true
}, - "otpSmsPage": {
- "title": "Verifica numero di telefono di cellulare",
- "subtitle": "Ti preghiamo di inserire il codice di verifica che invieremo al tuo numero di telefono cellulare",
- "showLogo": true
}, - "outcomePage": {
- "title": "Firma conclusa con successo",
- "titleRejected": "Firma rifiutata",
- "subtitle": "La procedura di firma è avvenuta con successo",
- "subtitleRejected": "La procedura di firma è stata rifiutata",
- "showLogo": true,
- "customLink": {
- "title": "Clicca qui per ritornare alla pagina principale",
- "redirectInSecs": 5
}
}
}, - "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "mandatoryTags": {
- "anyTagName": null
}
}This endpoint deletes a specific archetype, if there is no interaction with this archetype.
| archetypeId required | number Example: 85 |
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
curl -XDELETE "{SERVER}/archetypes/85" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" // TODO: Replace id:secret with the proper credentials
{- "id": 1,
- "name": "Archetype 1",
- "smsCustomMessage": "OTP: {{CODE}} - Enter the above code to sign your document",
- "smsCustomMessageModeratedOn": null,
- "fullNameSignatureFont": "LeagueScript",
- "signatureCustomisations": {
- "whitelabel": false,
- "fullNameSignatureFont": "LeagueScript",
- "signPage": {
- "title": "Accettazione termini di servizio",
- "showLogo": true
}, - "otpSmsPage": {
- "title": "Verifica numero di telefono di cellulare",
- "subtitle": "Ti preghiamo di inserire il codice di verifica che invieremo al tuo numero di telefono cellulare",
- "showLogo": true
}, - "outcomePage": {
- "title": "Firma conclusa con successo",
- "titleRejected": "Firma rifiutata",
- "subtitle": "La procedura di firma è avvenuta con successo",
- "subtitleRejected": "La procedura di firma è stata rifiutata",
- "showLogo": true,
- "customLink": {
- "title": "Clicca qui per ritornare alla pagina principale",
- "redirectInSecs": 5
}
}
}, - "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "mandatoryTags": {
- "anyTagName": null
}
}This solution offers an alternative to the "Document" ones, that allows a company to create interactions to apply click-to-sign electronic signatures. In this case the company may want to sign a contract or policy but in this case they won’t be within a PDF document but inside a web page.
Integrating this solution requires a little bit more effort since the signature interaction takes place inside a web page that must be rendered by the company before being presented to the signer.
Let's take into account the following initial scenario:
However, assume that the company wants to present in that web page a contract that needs to be signed with at least a Simple Electronic Signature (SES). The Webpage Forensic API allows the company to produce a SES with forensic probative value using proprietary and patented methodology that creates a forensic layer following the standard ISO/IEC 27037:2012, all of this without disrupting the company’s user experience. Therefore, for the signer it would be like nothing changed, but the company will have a strong signature that could be used irrefutably to prove that the interaction took place, in case of litigation. The following diagram shows, at a certain level of abstraction, how the interaction takes place once WT is integrated within the company's process.
variation set to full (the default value). The interaction object will contain a pre-rendered HTML page (the very same page that the company would have sent directly to the user) along with the URL where the company intends to handle the user's action (O-URL).The user's action must be sent to the WT gateway before reaching its final destination. Therefore, the company needs to specify
O-URLas a parameter while creating a new interaction. For the same reason, the company must replaceO-URLwithin the pre-rendered HTML with the placeholder<%= e_url %>.For instance, if the user's action is the submission of a form and
O-URLishttp://company_webserver.com/submitthe company has to:
- Replace
<form action="http://company_webserver.com/submit" method="post">with<form action="<%= e_url %>" method="post">inside the pre-rendered HTML the company will provide to WT,- Specify
http://company_webserver.com/submitas the parameterO-URLand full as the parameter variation. More details on these parameters can be found in the create interaction [operation/createInteraction] section.
F-URL) to which the company's Web Server must redirect the user.F-URL.F-URL endpoint in the WT gateway. This endpoint does not contain the actual page.E-URL) where the page will be served.E-URL is returned to the WT gateway.E-URL.E-URL served from the secured container.O-URL will be sent back to the user's browser.O-URL, served by the company.This extended process proposed by WT is an expansion of the normal interaction that would have taken place between the user and the company. Note that those are steps 1, 12, 17 and 18 of the previous diagram.
This solution allows a company to sign data flows coming from Single Page Applications (SPA), Native Applications or IoT (Internet of things) devices; also in this case the signatures happen within a forensic environment using a proprietary and patented methodology following the standard ISO/IEC 27037:2012. The key difference between this solution and the Webpage Forensic API is that in this case the context that produces the signature is not acquired forensically.
This workflow defines how to use WT to acquire a user's API call directed to the company's Web Server. For instance, an API call coming from a Single Page Application (SPA). The acquisition will include only the user's action that provoked an API call from the SPA. However, it will not include any context whatsoever (i.e. the SPA itself).
Let's take into account the following initial scenario:
Steps 1 and 2 are out of WT's scope. Hence we will focus from the moment of the API call onwards, losing this way any context the user may have had before submitting the action.
Let's assume the company wants to forensically sign the interaction that occurs between the user and the company's web server via an API call originating from the SPA.
The following diagram shows at a certain level of abstraction how the interaction takes place once WT is integrated within the company's process.
variation with value no_html.
The user's Request that the company wants to acquire with WT has to be sent to WT before reaching its final destination in the company's Web Server. It is paramount that the company specifies the O-URL as a parameter in the interaction creation, so when the process is concluding, WT can redirect the request to this Url.F-URL) to which the company's Web Server must redirect the user's API call.the first one implies a prior modification of the SPA. Assuming the API call is done from a button event handler, the following can be done:
async function eventHandler(...) { ...
// call the endpoint that will provoke the interaction creation let interactionResponse = await fetch(COMPANY_WEB_SERVER_URL, options);
// call the F-URL endpoint in the WT gateway let realResponse = await fetch(interactionResponse.fUrl, options);
... }
the second way uses the HTTP redirection mechanism. Using this way, the SPA does not need to be modified. However, it is necessary that the company's Web Server responds with an HTTP Redirect to F-URL using the HTTP code 307 to ensure the preservation of the method as well as the body.
E-URL). This Url will be an endpoint within WT, to where the action will be redirected in order to perform a forensic acquisition.E-URL is then returned to the WT gateway.E-URL using code 307.E-URL served from the secured container.O-URL will be sent back to the user's browser.O-URL served by the company.This extended process proposed by WT is an expansion of the normal interaction that would have taken place between the user and the company. Note that those are steps 1 and 16 of the previous flow.
Before you can acquire an action done by one of the users (and its context), you need to create a new interaction, and redirect the user to the forward URL (fUrl) specifically provided by WT. You will find this fUrl inside the body of the response of this call.
At the end of this call, remember to redirect your user to
fUrl!
Since we don't implement any of your backend business logic, the user's request needs eventually to be re-submitted to your web server. Therefore you must provide us with the oURL where the endpoint that receives the user request must reside.
This call supports two different variations: full or no_html. The first one corresponds to the case of Webpage Forensics API and the second one corresponds to the case of Data Forensics API.
If you use the full variation, you need to provide us with some HTML that will be the context on which the user is going to do his action. The user's action could be for instance a form submission (a POST or a GET) or the click on a link (only a GET). In both cases, you have to pre-render the HTML on your server and give it to us.
Within your pre-rendered HTML, remember to replace the URL where you originally intended to handle the user's action with the
<%= e_url %>placeholder.
Otherwise, if you use the no_html variation, WT will just acquire the single action coming from the user to your service (MITM'ed by WT) with no information about its context. In this case, you will not have to provide us any pre-rendered HTML.
Moreover, it is possible to specify a Callback URL where WT will send a POST request at the end of the single interaction process, stating if everything went OK (in this case, the body of the POST request will include the body sent from the user to our system) or if an error occurred.
You can also specify to make WT act as a proxy (actAsProxy) to your service, which means that the latter interaction to the specified oURL will happen from our servers instead of from your customer's client. This has the only disadvantage that you cannot set a cookie to your customer's client, otherwise there is no reason to not use this, given that you will have improved security (eg: no risk that a rogue customer's client can block/amend the request that will be sent to your server).
Finally, you can also decide to put any tag on your interaction.
Future retrievals requests can only be done by matching interaction IDs or custom tags! Otherwise, we won't be able to fetch the data contained in your pre-rendered HTML or in the content submitted by your user's action.
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
| Content-Type required | string Value: "application/json" |
Interaction creation object
| oURL required | string Original URL. The URL where the request was originally intended to go. At the end of the acquisition process, the user will automatically re-submit the request to this URL. The company's service must be ready to serve the user's request in this URL. |
| variation | string Default: "full" Enum: "full" "no_html" The variation you want to use, depending on whether the interaction is intended for server-side rendered web pages or api call. Therefore indicates if the interaction will have context or not. |
| isForensic | boolean Default: true Sets whether the interaction is forensic or not. Interactions that are not forensics will provide less information inside the final XML packet, for instance it won't contain the PCAP and KEYS. Also for non-forensic interaction a dedicated environment won't be spawned. |
| actAsProxy | boolean Default: false If set to true, WT will act as a proxy to your service, shipping directly the final interaction to your oURL instead of your customer's client. This is recommended. |
| prerenderedHtml | string The pre-prendered HTML to be displayed by WT's container web server. It must contain the string |
| archetypeId | integer >= 1 If the interation has an archetype, this field represents the archetypes's unique identifier. |
| extradata | string <= 262144 characters It is a free text field that can be used to store any kind of information |
object An object representing the tags to be added to the Interaction. Note: tag names can only contain US-ASCII letters and/or numbers, whereas tag values can be any UTF-8 string. The |
{- "variation": "full",
- "isForensic": true,
- "actAsProxy": true,
- "prerenderedHtml": "string",
- "archetypeId": 85,
- "extradata": "Extra data",
- "tags": {
- "crmUserId": "123",
- "erpInternalId": "456"
}
}You can use this endpoint to get all of your Interactions. In the future, you will also be able to search among interactions using custom tags (still to be implemented).
This endpoint retrieves all of your interactions. Please note that the attached files are not shown here: they are shown on a single-interaction basis.
| top | integer [ 1 .. 25 ] Default: 5 The maximum number of object to be returned. |
| skip | integer >= 0 Default: 0 The number of results to be skipped starting from the first result. Used for pagination. |
| sortBy | string Example: sortBy=oMethod,-createdAt A sorting criteria. It must be specified as comma separated list of terms, where each term can be:
For example a valid sorting criteria specification would be:
With this criteria you will get a list of interaction sorted by |
| oMethod | string Enum: "get" "post" "patch" "put" "option" "delete" The original method of the interaction. |
| variation | string Enum: "full" "no_html" The variation of the interaction. |
| currentStatus | string Enum: "SUBSCRIBED" "POD_FAILED" "CONCLUDING" "CONCLUDED" The current status of the interaction. |
| hasPrerenderedHtml | boolean Example: hasPrerenderedHtml=true Indicates whether the interaction contains the prerendered HTML show to the user or not. |
| createdAt | string Example: createdAt=2018-02-01T12:34:23|2018-04-01T12:34:23 Range of timestamps with one of the following formats:
|
| archetypeId | integer >= 1 Get the interactions corresponding to the specified archetype id. |
| tag:anyTagName | string Example: tag:anyTagName=tagValue You can filter your interactions by specifying a single |
| users | Array of strings Example: users=externalUserId1,externalUserId2 Only if you are an admin, you can get all of the interactions belonging to your specified users |
| Content-Type required | string Value: "application/json" |
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
curl "https://api.webtrust.kopjra.com/v1/interactions" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" # TODO: Replace id:secret with the proper credentials
[- {
- "id": 83,
- "oMethod": "get",
- "isForensic": true,
- "actAsProxy": true,
- "archetypeId": 85,
- "hasPrerenderedHtml": true,
- "expirationPeriod": 3600,
- "expiresAt": "2018-02-14T14:25:57.000Z",
- "deletedAt": "2018-02-14T14:25:57.000Z",
- "deletedEvidence": true,
- "userLandedAt": "2018-02-14T14:25:57.000Z",
- "userTookoffAt": "2019-02-14T14:25:57.000Z",
- "downloadableUntil": "2020-02-14T14:25:57.000Z",
- "currentStatus": "CONCLUDED",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "tags": {
- "crmUserId": "123",
- "erpInternalId": "456"
}
}
]This endpoint retrieves a specific interaction, including any tag and signed URLs that can be used to download any available attached file.
| interactionId required | number Example: 85 |
| Content-Type required | string Value: "application/json" |
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
curl "{SERVER}/interactions/85" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" // TODO: Replace id:secret with the proper credentials
{- "id": 83,
- "oMethod": "get",
- "isForensic": true,
- "actAsProxy": true,
- "archetypeId": 85,
- "hasPrerenderedHtml": true,
- "expirationPeriod": 3600,
- "expiresAt": "2018-02-14T14:25:57.000Z",
- "deletedAt": "2018-02-14T14:25:57.000Z",
- "deletedEvidence": true,
- "userLandedAt": "2018-02-14T14:25:57.000Z",
- "userTookoffAt": "2019-02-14T14:25:57.000Z",
- "downloadableUntil": "2020-02-14T14:25:57.000Z",
- "currentStatus": "CONCLUDED",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "tags": {
- "crmUserId": "123",
- "erpInternalId": "456"
}, - "extradata": "Extra data",
- "auditTrailXML": "<auditTrail>...</auditTrail>",
- "auditTrail": {
- "interactionId": 10,
- "createdAt": "2018-02-14T14:25:57.000Z",
- "digests": {
- "pcap": "125848e420c1f8dcadfc8d617c35588230b6683ebb9b0010b4b33345fe1e5545",
- "keys": "125848e420c1f8dcadfc8d617c35588230b6683ebb9b0010b4b33345fe1e5545",
- "authReqs": "125848e420c1f8dcadfc8d617c35588230b6683ebb9b0010b4b33345fe1e5545"
}, - "hostOS": "Debian Stretch",
- "communications": [
- {
- "id": "0d01550e-5e9a-41ad-846e-96ed80fb1f6b",
- "timestamps": {
- "request": "2018-02-14T14:25:57.000Z",
- "response": "2018-02-14T14:25:57.000Z"
}, - "ip": "134.45.3.35",
- "method": "GET",
- "url": "/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpX2lkIjoxNiwiaXNzIjoiaHR0cHM6Ly9hcGkuZ2F0ZXdheS5rb3BqcmEuY29tIiwiYXVkIjoiaHR0cHM6Ly9hcGkuZ2F0ZXdheS5rb3BqcmEuY29tIiwiaWF0IjoxNjAxMjgxMDM4LCJleHAiOjE2MDEyODE5MzJ9.MfFDZbfZ_WLjGCAJvtF8lF9Svz1mTIY_HeQgiGy9crU/sign",
- "originalUrl": "/token/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpX2lkIjoxNiwiaXNzIjoiaHR0cHM6Ly9hcGkuZ2F0ZXdheS5rb3BqcmEuY29tIiwiYXVkIjoiaHR0cHM6Ly9hcGkuZ2F0ZXdheS5rb3BqcmEuY29tIiwiaWF0IjoxNjAxMjgxMDM4LCJleHAiOjE2MDEyODE5MzJ9.MfFDZbfZ_WLjGCAJvtF8lF9Svz1mTIY_HeQgiGy9crU/sign",
- "responseStatus": {
- "code": 200,
- "message": "Everything OK"
}
}
], - "userArrivedAt": "2018-02-14T14:25:57.000Z",
- "userTookOffAt": "2018-02-14T14:25:57.000Z",
- "signedAt": "2018-02-14T14:25:57.000Z"
}, - "attachedFiles": {
- "xmlSize": 87541
}
}This endpoint marks a specific interaction as deleted. It will delete all evidence if present and mark the interaction as deleted (setting a date)
| interactionId required | number Example: 85 |
| Content-Type required | string Value: "application/json" |
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
curl -XDELETE "{SERVER}/interactions/85" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" // TODO: Replace id:secret with the proper credentials
{- "error": "Internal Server Error",
- "message": "An internal server error occurred"
}This solution allows us to create and manage Simple Electronic Signatures (SES) with a Forensic layer. With respect to a normal SES, by adding the proprietary and patented methodology that creates a forensic layer (following the standard ISO/IEC 27037:2012) WT offers a signature with a higher probatory value, positioning it between a SES and an AES. On top of that, in this signing process one can verify the identity of the signer by sending an OTP via SMS, adding more probative value.
The typical use case for this solution is a company that wants contracts to be signed electronically using a SES but needs more probative value in case of litigation, but does not want to provide an AES. The company must create this type of signatures using the endpoint [operation/createSignature] and specify the parameter isForensic = true (that is the default value) in the body, in addition to the remaining required parameters.
The following diagram shows, at a certain level of abstraction, how the signature interaction takes place once WT is integrated within the company's process.
isForensic = true. F-URL) to which the company will redirect the singer.F-URL.F-URL to WT.E-URL) where the page with the PDF will be served.E-URL is returned to WT.E-URL.E-URL served from the isolated secured container where the signature will effectively take place.This solution is fairly similar to the Document Simple Forensic API. It provides a Simple Electronic Signature (SES) with an audit trail, but in this case there won’t be an OTP identification and the audit trail is not forensic.
During the integration inside a Company’s process, to create a signature using this API, one must call the end point [operation/createSignature] although in this context using the property isForensic = false.
The following diagram shows, at a certain level of abstraction, how the signature interaction takes place once WT is integrated within the company's process.
isForensic = false. F-URL) to which the company will redirect the signer.F-URL.F-URL to WT.E-URL) where the page with the PDF will be served.E-URL is returned to WT.E-URL.E-URL served from the secured container where the signature will effectively take place.Creates a signature for the specified documents. The response will contain a link (fUrl) to the signature environment.
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
| Content-Type required | string Value: "application/json" |
Signature creation object
| signerFullname required | string Full name of the signer |
| signatureType required | string Enum: "graphic" "fullname_date" "none" Signature type can be a graphic stroke, an automatically generated text from the signer's fullname or nothing at all. |
| forcedSignaturePNGBase64 | string <byte> PNG in base64 to be forced as signature when the signatureType is |
| isForensic | boolean Default: true Sets whether the interaction is forensic or not. Interactions that are not forensics will provide less information inside the final XML packet, for instance it won't contain the PCAP and KEYS. Also for non-forensic interaction a dedicated environment won't be spawned. |
| ignoreDownloadAll | boolean Default: false If |
| pades | boolean Default: false If Note: If the following conditions are not met when
|
| locale | string Enum: "it" "en" "fr" "es" "de" Language to be used in the texts provided automatically in the signature environment. WARN! It is a responsibility of the caller to translate accordinly all other custom texts, like |
| extradata | string <= 262144 characters It is a free text field that can be used to store any kind of information |
required | Array of objects [ 1 .. 50 ] items Original documents to apply the graphical signature. |
object The OTP to be sent and verified | |
Array of objects >= 0 items Additional checkboxes to be added into the form of the signing page, external to the PDF document to be signed. | |
| archetypeId | integer >= 1 If the signature has an archetype, this field represents the archetype's unique identifier. |
object The customisations you applied to a Signature resource. Every field is optional. | |
| immediatePDFViewMobile | boolean Default: false If true immediately shows the PDF in the signing environment. This option can be true only when the amount of document is 1 |
| rejectable | boolean Default: false If true the interaction can be refused in the signing environment via a Refuse button under the main call to action. If the interaction is refused, the its status will be |
object An object representing the tags to be added to the Interaction. Note: tag names can only contain US-ASCII letters and/or numbers, whereas tag values can be any UTF-8 string. The |
{- "signerFullname": "string",
- "signatureType": "graphic",
- "forcedSignaturePNGBase64": "JVBERi0xLjYNJeLjz9MNCjI0IDA",
- "isForensic": true,
- "ignoreDownloadAll": false,
- "pades": false,
- "locale": "it",
- "extradata": "Extra data",
- "documents": [
- {
- "name": "Contratto",
- "contentBase64": "JVBERi0xLjYNJeLjz9MNCjI0IDA",
- "signatureFieldsType": "signature",
- "failSignature": "BOTTOM_RIGHT",
- "signatureFieldsName": [
- "Field Name"
], - "signatureFieldsMap": {
- "key1": "value1",
- "key2": [
- "value2",
- "value3"
]
}, - "markPages": "BOTTOM_LEFT",
- "tags": {
- "externalId": "ID"
}, - "compile": null,
- "applySignature": true,
- "conditionalSignatures": [
- {
- "name": "optional_insurance",
- "text": "Do you want to add an optional insurance as stated on Artt. 3, 4 and 7 of the contract?",
- "required": false,
- "signatureFieldsName": [
- "SIG_OPTIONAL_INSURANCE"
], - "signatureFieldsMap": {
- "key1": "value1",
- "key2": [
- "value2",
- "value3"
]
}, - "alert": true
}
], - "preprocess": [
- "SIGNATURE_PLACEHOLDERS"
]
}
], - "otp": {
- "sms": "+393331234567"
}, - "extraChecks": [
- {
- "name": "vessatorie",
- "text": "Accetto espressamente le clausole vessatorie corrispondenti agli artt. 4, 5 e 6 del |$|contratto|$|",
- "detail": "<h1>Policy</h1> <p>description of the policy</p>",
- "required": true
}
], - "archetypeId": 85,
- "signatureCustomisations": {
- "fullNameSignatureFont": "LeagueScript",
- "signPage": {
- "title": "Accettazione termini di servizio",
- "showLogo": true
}, - "otpSmsPage": {
- "title": "Verifica numero di telefono di cellulare",
- "subtitle": "Ti preghiamo di inserire il codice di verifica che invieremo al tuo numero di telefono cellulare",
- "showLogo": true
}, - "outcomePage": {
- "title": "Firma conclusa con successo",
- "titleRejected": "Firma rifiutata",
- "subtitle": "La procedura di firma è avvenuta con successo",
- "subtitleRejected": "La procedura di firma è stata rifiutata",
- "showLogo": true,
- "customLink": {
- "title": "Clicca qui per ritornare alla pagina principale",
- "redirectInSecs": 5
}
}
}, - "immediatePDFViewMobile": true,
- "rejectable": true,
- "tags": {
- "crmUserId": "123",
- "erpInternalId": "456"
}
}{- "id": 83,
- "signerFullname": "string",
- "signatureType": "graphic",
- "forcedSignaturePNGBase64": "JVBERi0xLjYNJeLjz9MNCjI0IDA",
- "isForensic": true,
- "ignoreDownloadAll": false,
- "pades": false,
- "locale": "it",
- "documents": [
- {
- "id": 123,
- "signedDocumentId": 124,
- "name": "Contratto",
- "signatureFieldsType": "signature",
- "failSignature": "BOTTOM_RIGHT",
- "signatureFieldsName": [
- "Field Name"
], - "signatureFieldsMap": {
- "key1": "value1",
- "key2": [
- "value2",
- "value3"
]
}, - "markPages": "BOTTOM_LEFT",
- "tags": {
- "externalId": "ID"
}, - "isSigned": true,
- "deletedAt": "2018-02-14T14:25:57.000Z",
- "conditionalSignatures": [
- {
- "index": "E",
- "name": "optional_insurance",
- "text": "Do you want to add an optional insurance as stated on Artt. 3, 4 and 7 of the contract?",
- "required": false,
- "signatureFieldsName": [
- "SIG_OPTIONAL_INSURANCE"
], - "signatureFieldsMap": {
- "key1": "value1",
- "key2": [
- "value2",
- "value3"
]
}, - "alert": true,
- "value": true
}
]
}
], - "otp": {
- "sms": "+393331234567"
}, - "extraChecks": [
- {
- "name": "vessatorie",
- "text": "Accetto espressamente le clausole vessatorie corrispondenti agli artt. 4, 5 e 6 del |$|contratto|$|",
- "detail": "<h1>Policy</h1> <p>description of the policy</p>",
- "required": true
}
], - "archetypeId": 85,
- "signatureCustomisations": {
- "fullNameSignatureFont": "LeagueScript",
- "signPage": {
- "title": "Accettazione termini di servizio",
- "showLogo": true
}, - "otpSmsPage": {
- "title": "Verifica numero di telefono di cellulare",
- "subtitle": "Ti preghiamo di inserire il codice di verifica che invieremo al tuo numero di telefono cellulare",
- "showLogo": true
}, - "outcomePage": {
- "title": "Firma conclusa con successo",
- "titleRejected": "Firma rifiutata",
- "subtitle": "La procedura di firma è avvenuta con successo",
- "subtitleRejected": "La procedura di firma è stata rifiutata",
- "showLogo": true,
- "customLink": {
- "title": "Clicca qui per ritornare alla pagina principale",
- "redirectInSecs": 5
}
}
}, - "immediatePDFViewMobile": true,
- "rejectable": true,
- "expirationPeriod": 86400,
- "expiresAt": "2018-02-14T14:25:57.000Z",
- "deletedAt": "2018-02-14T14:25:57.000Z",
- "deletedEvidence": true,
- "userLandedAt": "2018-02-14T14:25:57.000Z",
- "userTookoffAt": "2019-02-14T14:25:57.000Z",
- "downloadableUntil": "2020-02-14T14:25:57.000Z",
- "currentStatus": "CONCLUDED",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "tags": {
- "crmUserId": "123",
- "erpInternalId": "456"
},
}You can use this endpoint to get all of your Signatures. In the future, you will also be able to search among signatures using custom tags (still to be implemented).
This endpoint retrieves all of your signatures. Please note that the attached files are not shown here: they are shown on a single-signature basis.
| top | integer [ 1 .. 25 ] Default: 5 The maximum number of object to be returned. |
| skip | integer >= 0 Default: 0 The number of results to be skipped starting from the first result. Used for pagination. |
| sortBy | string Example: sortBy=oMethod,-createdAt A sorting criteria. It must be specified as comma separated list of terms, where each term can be:
For example a valid sorting criteria specification would be:
With this criteria you will get a list of signatures sorted by |
| signerFullname | string The full name of the signer. |
| currentStatus | string Enum: "SUBSCRIBED" "POD_FAILED" "CONCLUDING" "CONCLUDED" The current status of the signature. |
| createdAt | string Example: createdAt=2018-02-01T12:34:23|2018-04-01T12:34:23 Range of timestamps with one of the following formats:
|
| archetypeId | integer >= 1 Get the signatures corresponding to the specified archetype id. |
| tag:anyTagName | string Example: tag:anyTagName=tagValue You can filter your signatures by specifying a single |
| users | Array of strings Example: users=externalUserId1,externalUserId2 Only if you are an admin, you can get all of the signatures belonging to your specified users |
| Content-Type required | string Value: "application/json" |
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
curl "https://api.webtrust.kopjra.com/v1/signatures" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" # TODO: Replace id:secret with the proper credentials
[- {
- "id": 83,
- "signerFullname": "string",
- "signatureType": "graphic",
- "forcedSignaturePNGBase64": "JVBERi0xLjYNJeLjz9MNCjI0IDA",
- "isForensic": true,
- "ignoreDownloadAll": false,
- "pades": false,
- "locale": "it",
- "documents": [
- {
- "id": 123,
- "signedDocumentId": 124,
- "name": "Contratto",
- "signatureFieldsType": "signature",
- "failSignature": "BOTTOM_RIGHT",
- "signatureFieldsName": [
- "Field Name"
], - "signatureFieldsMap": {
- "key1": "value1",
- "key2": [
- "value2",
- "value3"
]
}, - "markPages": "BOTTOM_LEFT",
- "tags": {
- "externalId": "ID"
}, - "isSigned": true,
- "deletedAt": "2018-02-14T14:25:57.000Z",
- "conditionalSignatures": [
- {
- "index": "E",
- "name": "optional_insurance",
- "text": "Do you want to add an optional insurance as stated on Artt. 3, 4 and 7 of the contract?",
- "required": false,
- "signatureFieldsName": [
- "SIG_OPTIONAL_INSURANCE"
], - "signatureFieldsMap": {
- "key1": "value1",
- "key2": [
- "value2",
- "value3"
]
}, - "alert": true,
- "value": true
}
]
}
], - "otp": {
- "sms": "+393331234567"
}, - "extraChecks": [
- {
- "name": "vessatorie",
- "text": "Accetto espressamente le clausole vessatorie corrispondenti agli artt. 4, 5 e 6 del |$|contratto|$|",
- "detail": "<h1>Policy</h1> <p>description of the policy</p>",
- "required": true
}
], - "archetypeId": 85,
- "signatureCustomisations": {
- "fullNameSignatureFont": "LeagueScript",
- "signPage": {
- "title": "Accettazione termini di servizio",
- "showLogo": true
}, - "otpSmsPage": {
- "title": "Verifica numero di telefono di cellulare",
- "subtitle": "Ti preghiamo di inserire il codice di verifica che invieremo al tuo numero di telefono cellulare",
- "showLogo": true
}, - "outcomePage": {
- "title": "Firma conclusa con successo",
- "titleRejected": "Firma rifiutata",
- "subtitle": "La procedura di firma è avvenuta con successo",
- "subtitleRejected": "La procedura di firma è stata rifiutata",
- "showLogo": true,
- "customLink": {
- "title": "Clicca qui per ritornare alla pagina principale",
- "redirectInSecs": 5
}
}
}, - "immediatePDFViewMobile": true,
- "rejectable": true,
- "expirationPeriod": 86400,
- "expiresAt": "2018-02-14T14:25:57.000Z",
- "deletedAt": "2018-02-14T14:25:57.000Z",
- "deletedEvidence": true,
- "userLandedAt": "2018-02-14T14:25:57.000Z",
- "userTookoffAt": "2019-02-14T14:25:57.000Z",
- "downloadableUntil": "2020-02-14T14:25:57.000Z",
- "currentStatus": "CONCLUDED",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "tags": {
- "crmUserId": "123",
- "erpInternalId": "456"
}
}
]This endpoint retrieves a specific signature, including any tag and signed URLs that can be used to download any available attached file.
| signatureId required | number Example: 85 |
| Content-Type required | string Value: "application/json" |
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
curl "{SERVER}/signatures/85" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" // TODO: Replace id:secret with the proper credentials
{- "id": 83,
- "signerFullname": "string",
- "signatureType": "graphic",
- "forcedSignaturePNGBase64": "JVBERi0xLjYNJeLjz9MNCjI0IDA",
- "isForensic": true,
- "ignoreDownloadAll": false,
- "pades": false,
- "locale": "it",
- "documents": [
- {
- "id": 123,
- "signedDocumentId": 124,
- "name": "Contratto",
- "signatureFieldsType": "signature",
- "failSignature": "BOTTOM_RIGHT",
- "signatureFieldsName": [
- "Field Name"
], - "signatureFieldsMap": {
- "key1": "value1",
- "key2": [
- "value2",
- "value3"
]
}, - "markPages": "BOTTOM_LEFT",
- "tags": {
- "externalId": "ID"
}, - "isSigned": true,
- "deletedAt": "2018-02-14T14:25:57.000Z",
- "conditionalSignatures": [
- {
- "index": "E",
- "name": "optional_insurance",
- "text": "Do you want to add an optional insurance as stated on Artt. 3, 4 and 7 of the contract?",
- "required": false,
- "signatureFieldsName": [
- "SIG_OPTIONAL_INSURANCE"
], - "signatureFieldsMap": {
- "key1": "value1",
- "key2": [
- "value2",
- "value3"
]
}, - "alert": true,
- "value": true
}
]
}
], - "otp": {
- "sms": "+393331234567"
}, - "extraChecks": [
- {
- "name": "vessatorie",
- "text": "Accetto espressamente le clausole vessatorie corrispondenti agli artt. 4, 5 e 6 del |$|contratto|$|",
- "detail": "<h1>Policy</h1> <p>description of the policy</p>",
- "required": true
}
], - "archetypeId": 85,
- "signatureCustomisations": {
- "fullNameSignatureFont": "LeagueScript",
- "signPage": {
- "title": "Accettazione termini di servizio",
- "showLogo": true
}, - "otpSmsPage": {
- "title": "Verifica numero di telefono di cellulare",
- "subtitle": "Ti preghiamo di inserire il codice di verifica che invieremo al tuo numero di telefono cellulare",
- "showLogo": true
}, - "outcomePage": {
- "title": "Firma conclusa con successo",
- "titleRejected": "Firma rifiutata",
- "subtitle": "La procedura di firma è avvenuta con successo",
- "subtitleRejected": "La procedura di firma è stata rifiutata",
- "showLogo": true,
- "customLink": {
- "title": "Clicca qui per ritornare alla pagina principale",
- "redirectInSecs": 5
}
}
}, - "immediatePDFViewMobile": true,
- "rejectable": true,
- "expirationPeriod": 86400,
- "expiresAt": "2018-02-14T14:25:57.000Z",
- "deletedAt": "2018-02-14T14:25:57.000Z",
- "deletedEvidence": true,
- "userLandedAt": "2018-02-14T14:25:57.000Z",
- "userTookoffAt": "2019-02-14T14:25:57.000Z",
- "downloadableUntil": "2020-02-14T14:25:57.000Z",
- "currentStatus": "CONCLUDED",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "tags": {
- "crmUserId": "123",
- "erpInternalId": "456"
}, - "extradata": "Extra data",
- "auditTrailXML": "<auditTrail>...</auditTrail>",
- "auditTrail": {
- "interactionId": 10,
- "createdAt": "2018-02-14T14:25:57.000Z",
- "digests": {
- "pcap": "125848e420c1f8dcadfc8d617c35588230b6683ebb9b0010b4b33345fe1e5545",
- "keys": "125848e420c1f8dcadfc8d617c35588230b6683ebb9b0010b4b33345fe1e5545",
- "authReqs": "125848e420c1f8dcadfc8d617c35588230b6683ebb9b0010b4b33345fe1e5545"
}, - "hostOS": "Debian Stretch",
- "communications": [
- {
- "id": "0d01550e-5e9a-41ad-846e-96ed80fb1f6b",
- "timestamps": {
- "request": "2018-02-14T14:25:57.000Z",
- "response": "2018-02-14T14:25:57.000Z"
}, - "ip": "134.45.3.35",
- "method": "GET",
- "url": "/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpX2lkIjoxNiwiaXNzIjoiaHR0cHM6Ly9hcGkuZ2F0ZXdheS5rb3BqcmEuY29tIiwiYXVkIjoiaHR0cHM6Ly9hcGkuZ2F0ZXdheS5rb3BqcmEuY29tIiwiaWF0IjoxNjAxMjgxMDM4LCJleHAiOjE2MDEyODE5MzJ9.MfFDZbfZ_WLjGCAJvtF8lF9Svz1mTIY_HeQgiGy9crU/sign",
- "originalUrl": "/token/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpX2lkIjoxNiwiaXNzIjoiaHR0cHM6Ly9hcGkuZ2F0ZXdheS5rb3BqcmEuY29tIiwiYXVkIjoiaHR0cHM6Ly9hcGkuZ2F0ZXdheS5rb3BqcmEuY29tIiwiaWF0IjoxNjAxMjgxMDM4LCJleHAiOjE2MDEyODE5MzJ9.MfFDZbfZ_WLjGCAJvtF8lF9Svz1mTIY_HeQgiGy9crU/sign",
- "responseStatus": {
- "code": 200,
- "message": "Everything OK"
}
}
], - "userArrivedAt": "2018-02-14T14:25:57.000Z",
- "userTookOffAt": "2018-02-14T14:25:57.000Z",
- "signedAt": "2018-02-14T14:25:57.000Z"
}, - "attachedFiles": {
- "signedDocuments": [
- {
- "id": 124,
- "originalDocumentId": 123,
- "name": "contratto.pdf",
- "size": 2345443,
- "tags": {
- "externalId": "ID"
}
}
], - "documents": [
- {
- "id": 123,
- "name": "contratto.pdf",
- "size": 345234543,
- "tags": {
- "externalId": "ID"
}
}
]
}
}This endpoint marks a specific signature as deleted. It will delete all evidence if present and mark the signature as deleted (setting a date)
| signatureId required | number Example: 85 |
| Content-Type required | string Value: "application/json" |
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
curl -XDELETE "{SERVER}/signatures/85" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" // TODO: Replace id:secret with the proper credentials
{- "error": "Internal Server Error",
- "message": "An internal server error occurred"
}Create an AES Provider that could be then used to create and managed AES Signatures
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
| Content-Type required | string Value: "application/json" |
| name required | string <= 255 characters The name of the AES provider |
| email required | string <= 255 characters The email of the AES provider |
| vatNumber required | string(^IT[0-9]{11}$) The VAT number of the AES provider, starting with the country code (at this moment only |
{- "name": "AES Provider",
- "email": "aesprovider@email.com",
- "vatNumber": "IT12345678901"
}{- "id": 123,
- "name": "AES Provider",
- "email": "aesprovider@email.com",
- "vatNumber": "IT12345678901"
}You can use thus endpoint to get all of your registered AES Providers.
| top | integer [ 1 .. 25 ] Default: 5 The maximum number of object to be returned. |
| skip | integer >= 0 Default: 0 The number of results to be skipped starting from the first result. Used for pagination. |
| sortBy | string Example: sortBy=-name A sorting criteria. It must be specified as comma separated list of terms, where each term can be:
With this criteria you will get a list of signatures sorted by |
| name | string The name of the AES Provider |
string The email of the AES Provider | |
| vatNumber | string The vatNumber of the AES Provider |
| Content-Type required | string Value: "application/json" |
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
curl "https://api.webtrust.kopjra.com/v1/aesProviders" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" # TODO: Replace id:secret with the proper credentials
[- {
- "id": 123,
- "name": "AES Provider",
- "email": "aesprovider@email.com",
- "vatNumber": "IT12345678901"
}
]This endpoint retrieves a specific AES Provider.
| aesProviderId required | number Example: 2 |
| Content-Type required | string Value: "application/json" |
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
curl "{SERVER}/aesProvider/2" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" // TODO: Replace id:secret with the proper credentials
{- "id": 123,
- "name": "AES Provider",
- "email": "aesprovider@email.com",
- "vatNumber": "IT12345678901"
}ONLY FOR ADMINISTRATORS' USE: Please contact support@kopjra.com if you want to delete an AES Provider.
This endpoint marks a specific AES Provider as deleted. It won't be considered anymore for the creation of new signatures.
| aesProviderId required | number Example: 2 |
| Content-Type required | string Value: "application/json" |
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
curl -XDELETE "{SERVER}/aesProviders/2" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" // TODO: Replace id:secret with the proper credentials
{- "error": "Internal Server Error",
- "message": "An internal server error occurred"
}This solution allows us to create and manage Advanced Electronic Signatures (AES). The canonical use case for this solution is a company that wants contracts to be signed electronically and needs the signature to be AES (i.e. it needs recognition of the signer, PAdES signatures applied to the document and legally compliant archiving of the signed documents + the audit trail of the signature).
To create an AES first we need to create the AES provider. The AES provider is the subject that will dispense the signatures. For instance we could have the following scenario:
A Company uses our API to create signature interactions between a Provider and a Signer. Note that the Company and the Provider could be the same subject. Before creating an AES signature interaction the company must register at least one provider (it could be the company itself) using the API aesProviders. Once the provider has been registered, the company may create signatures between that provider and signers, using the API aesSignatures.
The following diagram shows, at a certain level of abstraction, how the signature interaction takes place once WT is integrated within the company's process, and the provider has been registered.
F-URL) to which the company will redirect the singer.F-URL.F-URL to WT.F-URL, but this time there is a SPID authentication token.F-URL with the SPID token set.E-URL) where the page with the PDF will be served.E-URL is returned to WT.E-URL.E-URL served from the secured container where the signature will effectively take place.To be defined
| aesProviderId required | number Example: 2 |
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
| Content-Type required | string Value: "application/json" |
Signature creation object
| signerFullname required | string Full name of the signer |
| signatureType required | string Enum: "graphic" "fullname_date" "none" Signature type can be a graphic stroke, an automatically generated text from the signer's fullname or nothing at all. |
| forcedSignaturePNGBase64 | string <byte> PNG in base64 to be forced as signature when the signatureType is |
| ignoreDownloadAll | boolean Default: false If |
| locale | string Enum: "it" "en" "fr" "es" "de" Language to be used in the texts provided automatically in the signature environment. WARN! It is a responsibility of the caller to translate accordinly all other custom texts, like |
| extradata | string <= 262144 characters It is a free text field that can be used to store any kind of information |
required | Array of objects [ 1 .. 50 ] items Original documents to apply the graphical signature. |
object The OTP to be sent and verified | |
Array of objects >= 0 items Additional checkboxes to be added into the form of the signing page, external to the PDF document to be signed. | |
| archetypeId | integer >= 1 If the signature has an archetype, this field represents the archetype's unique identifier. |
object The customisations you applied to a Signature resource. Every field is optional. | |
| immediatePDFViewMobile | boolean Default: false If true immediately shows the PDF in the signing environment. This option can be true only when the amount of document is 1 |
| rejectable | boolean Default: false If true the interaction can be refused in the signing environment via a Refuse button under the main call to action. If the interaction is refused, the its status will be |
object An object representing the tags to be added to the Interaction. Note: tag names can only contain US-ASCII letters and/or numbers, whereas tag values can be any UTF-8 string. The | |
| authProvider required | string Enum: "spid" "cie" The authentication provider |
| signerFiscalCode required | string^TINIT-.* The fiscal code of the signer |
{- "signerFullname": "string",
- "signatureType": "graphic",
- "forcedSignaturePNGBase64": "JVBERi0xLjYNJeLjz9MNCjI0IDA",
- "isForensic": true,
- "ignoreDownloadAll": false,
- "pades": false,
- "locale": "it",
- "extradata": "Extra data",
- "documents": [
- {
- "name": "Contratto",
- "contentBase64": "JVBERi0xLjYNJeLjz9MNCjI0IDA",
- "signatureFieldsType": "signature",
- "failSignature": "BOTTOM_RIGHT",
- "signatureFieldsName": [
- "Field Name"
], - "signatureFieldsMap": {
- "key1": "value1",
- "key2": [
- "value2",
- "value3"
]
}, - "markPages": "BOTTOM_LEFT",
- "tags": {
- "externalId": "ID"
}, - "compile": null,
- "applySignature": true,
- "conditionalSignatures": [
- {
- "name": "optional_insurance",
- "text": "Do you want to add an optional insurance as stated on Artt. 3, 4 and 7 of the contract?",
- "required": false,
- "signatureFieldsName": [
- "SIG_OPTIONAL_INSURANCE"
], - "signatureFieldsMap": {
- "key1": "value1",
- "key2": [
- "value2",
- "value3"
]
}, - "alert": true
}
], - "preprocess": [
- "SIGNATURE_PLACEHOLDERS"
]
}
], - "otp": {
- "sms": "+393331234567"
}, - "extraChecks": [
- {
- "name": "vessatorie",
- "text": "Accetto espressamente le clausole vessatorie corrispondenti agli artt. 4, 5 e 6 del |$|contratto|$|",
- "detail": "<h1>Policy</h1> <p>description of the policy</p>",
- "required": true
}
], - "archetypeId": 85,
- "signatureCustomisations": {
- "fullNameSignatureFont": "LeagueScript",
- "signPage": {
- "title": "Accettazione termini di servizio",
- "showLogo": true
}, - "otpSmsPage": {
- "title": "Verifica numero di telefono di cellulare",
- "subtitle": "Ti preghiamo di inserire il codice di verifica che invieremo al tuo numero di telefono cellulare",
- "showLogo": true
}, - "outcomePage": {
- "title": "Firma conclusa con successo",
- "titleRejected": "Firma rifiutata",
- "subtitle": "La procedura di firma è avvenuta con successo",
- "subtitleRejected": "La procedura di firma è stata rifiutata",
- "showLogo": true,
- "customLink": {
- "title": "Clicca qui per ritornare alla pagina principale",
- "redirectInSecs": 5
}
}
}, - "immediatePDFViewMobile": true,
- "rejectable": true,
- "tags": {
- "crmUserId": "123",
- "erpInternalId": "456"
}, - "authProvider": "spid",
- "signerFiscalCode": "TINIT-PRZLSU89R12A944G"
}{- "id": 83,
- "signerFullname": "string",
- "signatureType": "graphic",
- "forcedSignaturePNGBase64": "JVBERi0xLjYNJeLjz9MNCjI0IDA",
- "isForensic": null,
- "ignoreDownloadAll": false,
- "pades": null,
- "locale": "it",
- "documents": [
- {
- "id": 123,
- "signedDocumentId": 124,
- "name": "Contratto",
- "signatureFieldsType": "signature",
- "failSignature": "BOTTOM_RIGHT",
- "signatureFieldsName": [
- "Field Name"
], - "signatureFieldsMap": {
- "key1": "value1",
- "key2": [
- "value2",
- "value3"
]
}, - "markPages": "BOTTOM_LEFT",
- "tags": {
- "externalId": "ID"
}, - "isSigned": true,
- "deletedAt": "2018-02-14T14:25:57.000Z",
- "conditionalSignatures": [
- {
- "index": "E",
- "name": "optional_insurance",
- "text": "Do you want to add an optional insurance as stated on Artt. 3, 4 and 7 of the contract?",
- "required": false,
- "signatureFieldsName": [
- "SIG_OPTIONAL_INSURANCE"
], - "signatureFieldsMap": {
- "key1": "value1",
- "key2": [
- "value2",
- "value3"
]
}, - "alert": true,
- "value": true
}
]
}
], - "otp": {
- "sms": "+393331234567"
}, - "extraChecks": [
- {
- "name": "vessatorie",
- "text": "Accetto espressamente le clausole vessatorie corrispondenti agli artt. 4, 5 e 6 del |$|contratto|$|",
- "detail": "<h1>Policy</h1> <p>description of the policy</p>",
- "required": true
}
], - "archetypeId": 85,
- "signatureCustomisations": {
- "fullNameSignatureFont": "LeagueScript",
- "signPage": {
- "title": "Accettazione termini di servizio",
- "showLogo": true
}, - "otpSmsPage": {
- "title": "Verifica numero di telefono di cellulare",
- "subtitle": "Ti preghiamo di inserire il codice di verifica che invieremo al tuo numero di telefono cellulare",
- "showLogo": true
}, - "outcomePage": {
- "title": "Firma conclusa con successo",
- "titleRejected": "Firma rifiutata",
- "subtitle": "La procedura di firma è avvenuta con successo",
- "subtitleRejected": "La procedura di firma è stata rifiutata",
- "showLogo": true,
- "customLink": {
- "title": "Clicca qui per ritornare alla pagina principale",
- "redirectInSecs": 5
}
}
}, - "immediatePDFViewMobile": true,
- "rejectable": true,
- "expirationPeriod": 86400,
- "expiresAt": "2018-02-14T14:25:57.000Z",
- "deletedAt": "2018-02-14T14:25:57.000Z",
- "deletedEvidence": true,
- "userLandedAt": "2018-02-14T14:25:57.000Z",
- "userTookoffAt": "2019-02-14T14:25:57.000Z",
- "downloadableUntil": "2020-02-14T14:25:57.000Z",
- "currentStatus": "CONCLUDED",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "tags": {
- "crmUserId": "123",
- "erpInternalId": "456"
}, - "aesProviderId": 123,
- "authProvider": "spid",
- "signerFiscalCode": "TINIT-PRZLSU89R12A944G",
}You can use this endpoint to get all of your AES Signatures. In the future, you will also be able to search among signatures using custom tags (still to be implemented).
This endpoint retrieves all of your signatures. Please note that the attached files are not shown here: they are shown on a single-signature basis.
| aesProviderId required | number Example: 2 |
| top | integer [ 1 .. 25 ] Default: 5 The maximum number of object to be returned. |
| skip | integer >= 0 Default: 0 The number of results to be skipped starting from the first result. Used for pagination. |
| sortBy | string Example: sortBy=oMethod,-createdAt A sorting criteria. It must be specified as comma separated list of terms, where each term can be:
For example a valid sorting criteria specification would be:
With this criteria you will get a list of signatures sorted by |
| signerFullname | string The full name of the signer. |
| currentStatus | string Enum: "SUBSCRIBED" "POD_FAILED" "CONCLUDING" "CONCLUDED" The current status of the signature. |
| createdAt | string Example: createdAt=2018-02-01T12:34:23|2018-04-01T12:34:23 Range of timestamps with one of the following formats:
|
| archetypeId | integer >= 1 Get the signatures corresponding to the specified archetype id. |
| tag:anyTagName | string Example: tag:anyTagName=tagValue You can filter your signatures by specifying a single |
| Content-Type required | string Value: "application/json" |
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
curl "https://api.webtrust.kopjra.com/v1/aesProviders/2/aesSignatures" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" # TODO: Replace id:secret with the proper credentials
[- {
- "id": 83,
- "signerFullname": "string",
- "signatureType": "graphic",
- "forcedSignaturePNGBase64": "JVBERi0xLjYNJeLjz9MNCjI0IDA",
- "isForensic": null,
- "ignoreDownloadAll": false,
- "pades": null,
- "locale": "it",
- "documents": [
- {
- "id": 123,
- "signedDocumentId": 124,
- "name": "Contratto",
- "signatureFieldsType": "signature",
- "failSignature": "BOTTOM_RIGHT",
- "signatureFieldsName": [
- "Field Name"
], - "signatureFieldsMap": {
- "key1": "value1",
- "key2": [
- "value2",
- "value3"
]
}, - "markPages": "BOTTOM_LEFT",
- "tags": {
- "externalId": "ID"
}, - "isSigned": true,
- "deletedAt": "2018-02-14T14:25:57.000Z",
- "conditionalSignatures": [
- {
- "index": "E",
- "name": "optional_insurance",
- "text": "Do you want to add an optional insurance as stated on Artt. 3, 4 and 7 of the contract?",
- "required": false,
- "signatureFieldsName": [
- "SIG_OPTIONAL_INSURANCE"
], - "signatureFieldsMap": {
- "key1": "value1",
- "key2": [
- "value2",
- "value3"
]
}, - "alert": true,
- "value": true
}
]
}
], - "otp": {
- "sms": "+393331234567"
}, - "extraChecks": [
- {
- "name": "vessatorie",
- "text": "Accetto espressamente le clausole vessatorie corrispondenti agli artt. 4, 5 e 6 del |$|contratto|$|",
- "detail": "<h1>Policy</h1> <p>description of the policy</p>",
- "required": true
}
], - "archetypeId": 85,
- "signatureCustomisations": {
- "fullNameSignatureFont": "LeagueScript",
- "signPage": {
- "title": "Accettazione termini di servizio",
- "showLogo": true
}, - "otpSmsPage": {
- "title": "Verifica numero di telefono di cellulare",
- "subtitle": "Ti preghiamo di inserire il codice di verifica che invieremo al tuo numero di telefono cellulare",
- "showLogo": true
}, - "outcomePage": {
- "title": "Firma conclusa con successo",
- "titleRejected": "Firma rifiutata",
- "subtitle": "La procedura di firma è avvenuta con successo",
- "subtitleRejected": "La procedura di firma è stata rifiutata",
- "showLogo": true,
- "customLink": {
- "title": "Clicca qui per ritornare alla pagina principale",
- "redirectInSecs": 5
}
}
}, - "immediatePDFViewMobile": true,
- "rejectable": true,
- "expirationPeriod": 86400,
- "expiresAt": "2018-02-14T14:25:57.000Z",
- "deletedAt": "2018-02-14T14:25:57.000Z",
- "deletedEvidence": true,
- "userLandedAt": "2018-02-14T14:25:57.000Z",
- "userTookoffAt": "2019-02-14T14:25:57.000Z",
- "downloadableUntil": "2020-02-14T14:25:57.000Z",
- "currentStatus": "CONCLUDED",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "tags": {
- "crmUserId": "123",
- "erpInternalId": "456"
}, - "aesProviderId": 123,
- "authProvider": "spid",
- "signerFiscalCode": "TINIT-PRZLSU89R12A944G"
}
]This endpoint retrieves a specific AES signature, including any tag and signed URLs that can be used to download any available attached files.
| aesProviderId required | number Example: 2 |
| aesSignatureId required | number Example: 85 |
| Content-Type required | string Value: "application/json" |
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
curl "{SERVER}/aesProviders/2/aesSignatures/85" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" // TODO: Replace id:secret with the proper credentials
{- "id": 83,
- "signerFullname": "string",
- "signatureType": "graphic",
- "forcedSignaturePNGBase64": "JVBERi0xLjYNJeLjz9MNCjI0IDA",
- "isForensic": null,
- "ignoreDownloadAll": false,
- "pades": null,
- "locale": "it",
- "documents": [
- {
- "id": 123,
- "signedDocumentId": 124,
- "name": "Contratto",
- "signatureFieldsType": "signature",
- "failSignature": "BOTTOM_RIGHT",
- "signatureFieldsName": [
- "Field Name"
], - "signatureFieldsMap": {
- "key1": "value1",
- "key2": [
- "value2",
- "value3"
]
}, - "markPages": "BOTTOM_LEFT",
- "tags": {
- "externalId": "ID"
}, - "isSigned": true,
- "deletedAt": "2018-02-14T14:25:57.000Z",
- "conditionalSignatures": [
- {
- "index": "E",
- "name": "optional_insurance",
- "text": "Do you want to add an optional insurance as stated on Artt. 3, 4 and 7 of the contract?",
- "required": false,
- "signatureFieldsName": [
- "SIG_OPTIONAL_INSURANCE"
], - "signatureFieldsMap": {
- "key1": "value1",
- "key2": [
- "value2",
- "value3"
]
}, - "alert": true,
- "value": true
}
]
}
], - "otp": {
- "sms": "+393331234567"
}, - "extraChecks": [
- {
- "name": "vessatorie",
- "text": "Accetto espressamente le clausole vessatorie corrispondenti agli artt. 4, 5 e 6 del |$|contratto|$|",
- "detail": "<h1>Policy</h1> <p>description of the policy</p>",
- "required": true
}
], - "archetypeId": 85,
- "signatureCustomisations": {
- "fullNameSignatureFont": "LeagueScript",
- "signPage": {
- "title": "Accettazione termini di servizio",
- "showLogo": true
}, - "otpSmsPage": {
- "title": "Verifica numero di telefono di cellulare",
- "subtitle": "Ti preghiamo di inserire il codice di verifica che invieremo al tuo numero di telefono cellulare",
- "showLogo": true
}, - "outcomePage": {
- "title": "Firma conclusa con successo",
- "titleRejected": "Firma rifiutata",
- "subtitle": "La procedura di firma è avvenuta con successo",
- "subtitleRejected": "La procedura di firma è stata rifiutata",
- "showLogo": true,
- "customLink": {
- "title": "Clicca qui per ritornare alla pagina principale",
- "redirectInSecs": 5
}
}
}, - "immediatePDFViewMobile": true,
- "rejectable": true,
- "expirationPeriod": 86400,
- "expiresAt": "2018-02-14T14:25:57.000Z",
- "deletedAt": "2018-02-14T14:25:57.000Z",
- "deletedEvidence": true,
- "userLandedAt": "2018-02-14T14:25:57.000Z",
- "userTookoffAt": "2019-02-14T14:25:57.000Z",
- "downloadableUntil": "2020-02-14T14:25:57.000Z",
- "currentStatus": "CONCLUDED",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "tags": {
- "crmUserId": "123",
- "erpInternalId": "456"
}, - "aesProviderId": 123,
- "authProvider": "spid",
- "signerFiscalCode": "TINIT-PRZLSU89R12A944G",
- "extradata": "Extra data",
- "auditTrailXML": "<auditTrail>...</auditTrail>",
- "auditTrail": {
- "interactionId": 10,
- "createdAt": "2018-02-14T14:25:57.000Z",
- "digests": {
- "pcap": "125848e420c1f8dcadfc8d617c35588230b6683ebb9b0010b4b33345fe1e5545",
- "keys": "125848e420c1f8dcadfc8d617c35588230b6683ebb9b0010b4b33345fe1e5545",
- "authReqs": "125848e420c1f8dcadfc8d617c35588230b6683ebb9b0010b4b33345fe1e5545"
}, - "hostOS": "Debian Stretch",
- "communications": [
- {
- "id": "0d01550e-5e9a-41ad-846e-96ed80fb1f6b",
- "timestamps": {
- "request": "2018-02-14T14:25:57.000Z",
- "response": "2018-02-14T14:25:57.000Z"
}, - "ip": "134.45.3.35",
- "method": "GET",
- "url": "/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpX2lkIjoxNiwiaXNzIjoiaHR0cHM6Ly9hcGkuZ2F0ZXdheS5rb3BqcmEuY29tIiwiYXVkIjoiaHR0cHM6Ly9hcGkuZ2F0ZXdheS5rb3BqcmEuY29tIiwiaWF0IjoxNjAxMjgxMDM4LCJleHAiOjE2MDEyODE5MzJ9.MfFDZbfZ_WLjGCAJvtF8lF9Svz1mTIY_HeQgiGy9crU/sign",
- "originalUrl": "/token/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpX2lkIjoxNiwiaXNzIjoiaHR0cHM6Ly9hcGkuZ2F0ZXdheS5rb3BqcmEuY29tIiwiYXVkIjoiaHR0cHM6Ly9hcGkuZ2F0ZXdheS5rb3BqcmEuY29tIiwiaWF0IjoxNjAxMjgxMDM4LCJleHAiOjE2MDEyODE5MzJ9.MfFDZbfZ_WLjGCAJvtF8lF9Svz1mTIY_HeQgiGy9crU/sign",
- "responseStatus": {
- "code": 200,
- "message": "Everything OK"
}
}
], - "userArrivedAt": "2018-02-14T14:25:57.000Z",
- "userTookOffAt": "2018-02-14T14:25:57.000Z",
- "signedAt": "2018-02-14T14:25:57.000Z"
}, - "attachedFiles": {
- "xml": {
- "size": 87541,
}, - "signedDocuments": [
- {
- "id": 124,
- "originalDocumentId": 123,
- "name": "contratto.pdf",
- "size": 2345443,
- "tags": {
- "externalId": "ID"
},
}
], - "documents": [
- {
- "id": 123,
- "name": "contratto.pdf",
- "size": 345234543,
- "tags": {
- "externalId": "ID"
}
}
]
}
}This endpoint marks a specific AES signature as deleted. It will delete all evidence if present and mark the signature as deleted (setting a date)
| aesProviderId required | number Example: 2 |
| aesSignatureId required | number Example: 85 |
| Content-Type required | string Value: "application/json" |
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
curl -XDELETE "{SERVER}/aesProviders/2/aesSignatures/85" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" // TODO: Replace id:secret with the proper credentials
{- "error": "Internal Server Error",
- "message": "An internal server error occurred"
}This API solution allows you to timestamp any data flow, like documents and log files. There are two types of timestamp that could be used:
To create a timestamp we just need to make an API call to the endpoint createTimestamp passing a binary body containing the data to be timestamped. While creating the timestamp we can select what type to use by specifying the parameter trusted that can be true or false.
Calling this method one can timestamp a data flow by using a trusted timestamp (using a Trust Service Provider) or using an open-timestamp (based on Bitcoin)
| sync | boolean Value: true Example: sync=true Indicates whether the stamp will be synchronous or asynchronous. Synchronous meaning the this call will end with a timestamped data flow as a response.
For now, this parameter must always be |
| trusted | boolean Example: trusted=false If |
| fileName | string Example: fileName=file.log The name of the file to be timestamped. |
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/octet-stream" |
| Content-Type required | string Value: "application/octet-stream" |
curl "{SERVER}/timestamps?sync=true&trusted=false&fileName=file.log" -X POST --data-binary "@./file.log" -H "Accept: application/octet-stream" -H "Content-Type: application/octet-stream" -H "Authorization: Basic id:secret" # TODO: Replace id:secret with the proper credentials
{- "error": "Bad Request"
}To make API calls to WT credentials are needed for the Authorization header. There are two ways of creating new credentials:
Note that the first time the developer portal must be used to create the credentials.
This API call will allow you to create new credentials. Credentials are not exclusive, they accumulate. A user can create a maximum of 2 credentials.
The secret will only be visible at the moment of the creation the credentials. So any further visualization of the credential won't contain the secret.
| Authorization required | string Example: Basic <base64-credential-string> |
| X-Impersonate-User | string Example: <externalUserId> |
empty object
{ }{- "id": "99a23d0349ad4c30e49dd08089507d4bb097e89ecb51d351158e30de0bdf321e94f848ce877336a5a7d0720a463b6ee8b80f1aa83581d42f7493d84bbc1b1dce",
- "secret": "akfW02-fr2yQpt-XscaNpEosF0-99VoaK8Ox-lbeJR0xaD2cDOgNFxJ9i_4QRNjDhVvsevYy4qGoIG6r3w3yIUTNsS90niyLBnyF7jXIHTc1h7GBhRYMaAx8uTKhuy3QyLd2-xz4avjef0uPf_lhJF_3uvu0BZwb0RNQPWF_LKo"
}This API call will allow you to retrieve all the credentials associated to the user (or the impersonated one).
Note that the
secretis not visible anymore.
| Authorization required | string Example: Basic <base64-credential-string> |
| X-Impersonate-User | string Example: <externalUserId> |
curl "{SERVER}/users/current/credentials" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" // TODO: Replace id:secret with the proper credentials
[- {
- "id": "99a23d0349ad4c30e49dd08089507d4bb097e89ecb51d351158e30de0bdf321e94f848ce877336a5a7d0720a463b6ee8b80f1aa83581d42f7493d84bbc1b1dce"
}
]This endpoint allows you to delete a credential. From the moment this is done, the removed credential can not be used anymore in the Authorization header to authenticate an API call.
| credentialId required | string Example: 99a23d0349ad4c30e49dd08089507d4bb097e89ecb51d351158e30de0bdf321e94f848ce... |
| Authorization required | string Example: Basic <base64-credential-string> |
| X-Impersonate-User | string Example: <externalUserId> |
curl "https://api.webtrust.kopjra.com/v1/users/current/credentials/99a23d0349ad4c30e49dd08089507d4bb097e89ecb51d351158e30de0bdf321e94f848ce877336a5a7d0720a463b6ee8b80f1aa83581d42f7493d84bbc1b1dce" -X DELETE -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" // TODO: Replace id:secret with the proper credentials
{- "error": "Forbidden",
- "message": "User cannot be impersonated"
}Callbacks are a way to notify the company's systems that a certain interaction/signature has changed status. The callback is sent to the company's system via a POST request to the URL specified in the callback's property endpoint.
The callbacks will be persistent and authenticated. If the registered endpoint goes in timeout or does not answer with an HTTP code different from 2xx, then the system will automatically retry the delivery according to the following schema:
Furthermore, since the callbacks are authenticated using HMAC with SHA-256, one could optionally verify the authenticity of the payload.
Each callback call will include the following headers:
svix-id: the unique message identifier for the webhook message. This identifier is unique across all messages, but will be the same when the same webhook is being resent (e.g. due to a previous failure).svix-timestamp: timestamp in seconds since epoch.svix-signature: the Base64 encoded list of signatures (space delimited).To verify the authenticity of the callback, one can use the following algorithm:
Concatenate the svix-id, svix-timestamp and the request body using a . as separator. For example: `${svix-id}.${svix-timestamp}.${body}`.
Use the base64 part of the secret as the key to sign the concatenated string using HMAC SHA256. For example in NodeJs:
const crypto = require('crypto');
signedContent = ${svix_id}.${svix_timestamp}.${body};
const secret = "whsec_5WbX5kEWLlfzsGNjH64I8lOOqUB6e8FH";
// Need to base64 decode the secret
const secretBytes = new Buffer(secret.split('_')[1],
"base64");
const signature = crypto
.createHmac('sha256', secretBytes)
.update(signedContent)
.digest('base64');
Now we have to compare the signature obtained in step 2 with the header svix-signature. The svix-signature header is composed of a list of space delimited signatures in base64 and their corresponding version identifiers. The signature list is most commonly of length one. Though there could be any number of signatures. For example:
v1,base64 v1,base64 v2,base64
Make sure to remove the version prefix and delimiter (e.g. v1,) before verifying the signature.
Finally compare signature with each of the signatures in svix-signature and at least one should match.
This API call will allow you to create new callback subscriptions. The designated endpoint will receive a callback when a relevant event happens.
| Authorization required | string Example: Basic <base64-credential-string> |
| X-Impersonate-User | string Example: <externalUserId> |
Interaction creation object
| kind | string Deprecated Value: "simple-http" The kind of callback (currently only 'simple-http'). Ignored and no longer used. |
| resourceType required | string Enum: "Interaction" "Signature" The type of resource to receive the callback. |
| endpoint required | string The endpoint of the callback subscription |
| onlyFinalStatuses | boolean Default: true If true, the callback is called only when resources of the type defined get to a final status. Otherwise, the callback is called whenever resources change status. |
| events | Array of strings Items Value: "USER_CONCLUDED" If set (together with |
{- "kind": "simple-http",
- "resourceType": "Interaction",
- "onlyFinalStatuses": false,
- "events": [
- "USER_CONCLUDED"
]
}{- "id": 123,
- "kind": "simple-http",
- "resourceType": "Interaction",
- "onlyFinalStatuses": false,
- "events": [
- "USER_CONCLUDED"
], - "secret": "whsec_5WbX5kEWLlfzsGNjH64I8lOOqUB6e8FH"
}This API call will allow you to retrieve all the callbacks associated to the user (or the impersonated one).
| Authorization required | string Example: Basic <base64-credential-string> |
| X-Impersonate-User | string Example: <externalUserId> |
curl "{SERVER}/users/current/callbacks" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" // TODO: Replace id:secret with the proper credentials
[- {
- "id": 123,
- "kind": "simple-http",
- "resourceType": "Interaction",
- "onlyFinalStatuses": false,
- "events": [
- "USER_CONCLUDED"
], - "secret": "whsec_5WbX5kEWLlfzsGNjH64I8lOOqUB6e8FH"
}
]This endpoint allows you to delete a callback. From the moment this is done, the removed endpoint will no longer receive any callback notification.
| callbackId required | string Example: 123 |
| Authorization required | string Example: Basic <base64-credential-string> |
| X-Impersonate-User | string Example: <externalUserId> |
curl "{SERVER}/users/current/credentials/123" -X DELETE -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" // TODO: Replace id:secret with the proper credentials
{- "error": "Forbidden",
- "message": "User cannot be impersonated"
}The acquisition package (outcome of an interaction), is downloadable for a certain amount of time, specified by the interaction's property downloadableUntil. To avoid that the company finds itself in a situation where it isn't able to download its acquisitions anymore, we devised an automatic Archiving mechanism.
This mechanism creates and indexed standalone package with all the interactions that took place within the a year (from January 1st to December 31st). This package is downloadable for a month from its creation, and afterwards it will be deleted from our systems.
Retrieves all the corresponding archives to the authenticated user.
| Content-Type required | string Value: "application/json" |
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
curl "{SERVER}/archives" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" // TODO: Replace id:secret with the proper credentials
[- {
- "id": 1,
- "startsOn": "2019-01-01T00:00:00Z",
- "endsOn": "2019-12-31T23:59:59Z",
- "targetResources": [
- "INTERACTION_EXPORT"
], - "expiresOn": "2020-02-01T00:00:00Z",
- "partMaxDimension": "DVD_SINGLE_SIDED_SINGLE_LAYER",
- "format": "ZIP_EXPORT",
- "sizeByte": 1343432145,
- "status": "READY"
}
]Retrieves an specific archive.
| archiveId required | number Example: 123 |
| Content-Type required | string Value: "application/json" |
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
curl "{SERVER}/archives/1" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" // TODO: Replace id:secret with the proper credentials
{- "id": 1,
- "startsOn": "2019-01-01T00:00:00Z",
- "endsOn": "2019-12-31T23:59:59Z",
- "targetResources": [
- "INTERACTION_EXPORT"
], - "expiresOn": "2020-02-01T00:00:00Z",
- "partMaxDimension": "DVD_SINGLE_SIDED_SINGLE_LAYER",
- "format": "ZIP_EXPORT",
- "sizeByte": 1343432145,
- "status": "READY"
}Retrieves all the parts associated to the specified archive.
| archiveId required | number Example: 123 |
| Content-Type required | string Value: "application/json" |
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
curl "{SERVER}/archives/1/parts" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" // TODO: Replace id:secret with the proper credentials
[- {
- "id": 1,
- "num": 1,
- "sizeByte": 4692251770,
- "downloadUrlExpiresOn": "2019-08-24T14:15:22Z",
- "status": "DOWNLOADABLE",
- "lastTransaction": {
- "fromStatus": "CREATING",
- "toStatus": "DOWNLOADABLE",
- "on": "2019-08-24T14:15:22Z",
- "msg": "The part is now ready to be downloaded."
}
}
]Retrieves a specific parts associated to the specified archive.
| archiveId required | number Example: 123 |
| partId required | number Example: 456 |
| Content-Type required | string Value: "application/json" |
| Authorization required | string Example: Basic <base64-credential-string> |
| Accept required | string Value: "application/json" |
curl "{SERVER}/archives/1/parts" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Basic id:secret" // TODO: Replace id:secret with the proper credentials
{- "id": 1,
- "num": 1,
- "sizeByte": 4692251770,
- "downloadUrlExpiresOn": "2019-08-24T14:15:22Z",
- "status": "DOWNLOADABLE",
- "lastTransaction": {
- "fromStatus": "CREATING",
- "toStatus": "DOWNLOADABLE",
- "on": "2019-08-24T14:15:22Z",
- "msg": "The part is now ready to be downloaded."
}
}