API documentation
General information
There are two environments for working with Vespia API: Development and Production.
Development environment dedicated to supporting the development of your application. It uses two endpoints for additional security measures - one for authentication and the other for data exchange.
- The authentication endpoint is https://dev-api.vespia.io/auth/graphql
- The data exchange endpoint is https://dev-api.vespia.io/my/graphql
The production environment, as the name says, is for using Vespia API on the production.
To switch from Development to production, you must change endpoints and repeat the SignIn step from authentication to get a new access token.
- The production authentication endpoint is https://api.vespia.io/auth/graphql
- The data exchange endpoint is https://api.vespia.io/my/graphql
All requests to this API must contain the authorization token:
1Authorization: Bearer $token
In this documentation, we are using the Development environment in the examples.
You can test data exchange API using the ApolloGraphQL client using this link. Alternatively, you can use Postman for tests. In this case, please make sure you use GraphQL Explorer to test the API, more details on how to use GraphQL with Postman: https://blog.postman.com/announcing-postmans-new-graphql-client/
Authentication
To access the data exchange endpoint (https://dev-api.vespia.io/my/graphql) you must send the access token in the Authorization header of each request.
Access token and its update
- Start with registering in the system. For development purposes, please create an account at https://dev-my.vespia.io/sign-up. Remember your login email and password.
- To receive the access token, you should use the signIn mutation in GraphQL or HTTP request way.
- When you switch from the Development to the Production environment, please use your account created at https://my.vespia.io/sign-up
Operation example
1Authorization: Bearer $token
Variables example
1{
2 "input": {
3 "email": "john@example.com",
4 "password": "E4Wd9Rdos-wij+$38weEE"
5 }
6}
Operation example
1{
2 "data": {
3 "refreshTokenPair": {
4 "refreshToken": "refresh-session:f82ec32d-e0c9-4846-8b64-8ca2d76514d1",
5 "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOiIwZGI
6 4MTY1NS04OTNlLTRjZjUtYTMzOS0yMjM1YjY1YTE3NjkiLCJlbWFpbCI6ImFsb3ppbnNre
7 UBtZS5jb20iLCJpc0FkbWluIjpmYWxzZSwiYWNjb3VudEdyb3VwcyI6W10sImlhdCI6MTcwNzkyNz
8 M2MywiZXhwIjoxNzA4NTI3MzYzfQ.27w7yo496JwQshA3MyHQ37OyeGdE3yR0XCg2047CDAQ"
9 }
10 }
11}
Object types and field descriptions.
For security reasons, the access token expires within 10 minutes. After that time, you have to refresh it using the
refreshTokenPair
mutation.Operation example
1mutation refreshTokenPair ($input: RefreshTokenPairInput!) {
2 refreshTokenPair(input: $input) {
3 refreshToken
4 token
5 }
6}
Variables example
1{
2 "input": {
3 "email": "john@example.com",
4 "password": "E4Wd9Rdos-wij+$38weEE"
5 }
6}
Object types and field descriptions
Diagram
The built-in playground is a user interface that allows developers to interact with the authentication-related queries and mutations of a GraphQL API. It displays all available queries and mutations, along with the parameters that can be passed and the data that is returned. This makes it easy to test and debug authentication-related code and see the results in real-time.
All available queries and mutations with arguments and returned fields can be viewed by following this link or by pressing the Expand button in the sandbox.
Playground
Verification procedure
Fast and slow countries
Countries are divided into fast and slow. For fast countries, business information is available immediately; for slow countries, processing time depends of jurisdiction and takes from 15 minutes to 24 hours on average.
To get information about entities from fast countries, you should use
requestKybVerification
and requestKycVerification
mutations.For slow countries and when you need more information, use
RequestEntityChecks
mutation.To determine which country is fast or slow, use the
countries
query.Operation example
1query Countries {
2 countries {
3 code
4 name
5 isVatAvailable
6 isBusinessAvailable
7 isDocumentAvailable
8 isUboAvailable
9 isDemo
10 }
11}
Response example
1
2 "data": {
3 "countries": [
4 {
5 "code": "UK",
6 "name": "United Kingdom",
7 "isVatAvailable": false,
8 "isBusinessAvailable": true,
9 "isDocumentAvailable": false,
10 "isUboAvailable": false,
11 "isDemo": true
12 },
13 {
14 "code": "ID",
15 "name": "Indonesia",
16 "isVatAvailable": false,
17 "isBusinessAvailable": false,
18 "isDocumentAvailable": false,
19 "isUboAvailable": false,
20 "isDemo": false
21 },
22……]
23}}
Object types and field descriptions
KYB verification (Business)
To perform business verification (KYB), you must start with the
requestKybVerification
mutation. It returns an array of EntityCheck
objectsOperation example
1mutation RequestKybVerification($input: RequestKybVerificationInput!) {
2 requestKybVerification(input: $input) {
3 id
4 type
5 status
6 result
7 dataRequestInfo
8 dataRequestId
9 folderId
10 comment
11 input
12 createdAt
13 updatedAt
14 expiredAt
15 account {
16 id
17 groupId
18 }
19 }
20}
Variables example
1{
2 "input": {
3 "countryCode": "EE",
4 "name": "Vespia",
5 "registrationCode": "EE102360253"
6 }
7}
Response example
1{
2 "data": {
3 "requestKybVerification": [
4 {
5 "id": "09130a7e-a06c-4256-a83e-390431ffb294",
6 "type": "BUSINESS_INFO",
7 "status": "AWAITING_CHECK",
8 "result": null,
9 "dataRequestInfo": null,
10 "dataRequestId": "32689c3b-3bf3-483f-9825-44d4961d8cbb",
11 "folderId": "21831f3d-ca25-44a0-9096-f77d34340d1f",
12 "comment": null,
13 "input": {
14 "name": "Vespia",
15 "countryCode": "EE",
16 "registrationCode": "EE102360253",
17 "account": {
18 "accountId": "0db81655-893e-4cf5-a339-2235b65a1769"
19 },
20 "folderId": "21831f3d-ca25-44a0-9096-f77d34340d1f",
21 "isCorporate": true
22 },
23 "createdAt": "2024-02-18T10:51:30.320Z",
24 "updatedAt": "2024-02-18T10:51:30.320Z",
25 "expiredAt": null,
26 "account": {
27 "id": "0db81655-893e-4cf5-a339-2235b65a1769",
28 "groupId": null
29 }
30 },
31 {
32 "id": "584779fd-908e-4ff3-9c74-c4fa7b7014dd",
33 "type": "UBO",
34 "status": "AWAITING_CHECK",
35 "result": null,
36 "dataRequestInfo": null,
37 "dataRequestId": "7afd17cb-99b3-4c07-bd16-3838e8d9366c",
38 "folderId": "21831f3d-ca25-44a0-9096-f77d34340d1f",
39 "comment": null,
40 "input": {
41 "name": "Vespia",
42 "countryCode": "EE",
43 "registrationCode": "EE102360253",
44 "account": {
45 "accountId": "0db81655-893e-4cf5-a339-2235b65a1769"
46 },
47 "folderId": "21831f3d-ca25-44a0-9096-f77d34340d1f",
48 "isCorporate": true
49 },
50 "createdAt": "2024-02-18T10:51:30.320Z",
51 "updatedAt": "2024-02-18T10:51:30.320Z",
52 "expiredAt": null,
53 "account": {
54 "id": "0db81655-893e-4cf5-a339-2235b65a1769",
55 "groupId": null
56 }
57 },
58 {
59 "id": "fd5f3a0a-f8a8-42db-afcc-916c1bd5dcf9",
60 "type": "VAT",
61 "status": "AWAITING_CHECK",
62 "result": null,
63 "dataRequestInfo": null,
64 "dataRequestId": "eaa13b12-d577-4d71-8df7-70b366420407",
65 "folderId": "21831f3d-ca25-44a0-9096-f77d34340d1f",
66 "comment": null,
67 "input": {
68 "countryCode": "EE",
69 "name": "Vespia"
70 },
71 "createdAt": "2024-02-18T10:51:30.320Z",
72 "updatedAt": "2024-02-18T10:51:30.320Z",
73 "expiredAt": null,
74 "account": {
75 "id": "0db81655-893e-4cf5-a339-2235b65a1769",
76 "groupId": null
77 }
78 }
79 ]
80 }
81}
Object types and field descriptions
Diagram
KYC verification (Person)
To perform customer verification (KYC), you must start with the
requestKycVerification
mutation. It returns an array of EntityCheck
objectsOperation example
1{
2 "input": {
3 "country": "UK",
4 "gender": "male",
5 "kind": "ID",
6 "name": [
7 "Boris",
8 "Johnson"
9 ],
10 "dob": "June 19, 1964",
11 "email": "boris.johnson@example.com"
12 }
13}
Variables example
1{
2 "data": {
3 "requestKycVerification": [
4 {
5 "id": "90b75ea3-0bc6-4f80-a633-6bf79c01616a",
6 "type": "ID",
7 "status": "AWAITING_CHECK",
8 "result": null,
9 "dataRequestInfo": null,
10 "dataRequestId": "d3c56dbf-4d52-4b97-b75c-a3fb59bee3cd",
11 "folderId": "878e1dae-6601-4f76-a33d-376fb0136929",
12 "comment": null,
13 "input": {
14 "sendEmailNotification": true,
15 "name": "Boris Johnson",
16 "email": "boris.johnson@example.com",
17 "dob": "June 19, 1964",
18 "gender": "male",
19 "country": "UK",
20 "account": {
21 "accountId": "0db81655-893e-4cf5-a339-2235b65a1769"
22 },
23 "folderId": "878e1dae-6601-4f76-a33d-376fb0136929",
24 "isCorporate": false
25 },
26 "createdAt": "2024-02-18T13:35:34.137Z",
27 "updatedAt": "2024-02-18T13:35:34.137Z",
28 "expiredAt": null,
29 "account": {
30 "id": "0db81655-893e-4cf5-a339-2235b65a1769",
31 "groupId": null
32 }
33 }
34 ]
35 }
36}
Object types and field descriptions
Diagram
Playground
More information about checks
To get more information about every check from the array
When all entity checks are completed in a Folder, the status field in the response to the query Folder should be Completed. Accordingly, you will be able to find the results of all checks, such as AML, in the response.
When you make a folder request, the response contains one of the fields, which is called
EntityCheck
, use the query Folder
with the correspondent value of folderId
as the argument. In this context, a folder should be considered a global entity that contains all the information about your verification.When all entity checks are completed in a Folder, the status field in the response to the query Folder should be Completed. Accordingly, you will be able to find the results of all checks, such as AML, in the response.
When you make a folder request, the response contains one of the fields, which is called
entities
, it contains an array. Entities are all persons and companies that belong to the company you are checking. Accordingly, in this array of entities, each entity contains entityChecks
, these are checks that you performed on the entity, for example, AML or ID.Operation example
1query Folder($folderId: UUID!) {
2 folder(id: $folderId) {
3 id
4 name
5 subCustomerEmail
6 account {
7 id
8 email
9 createdAt
10 updatedAt
11 profile
12 accountGroups {
13 id
14 name
15 domain
16 isProPlan
17 isAmlMonitoringAvailable
18 isRiskScoringAvailable
19 }
20 }
21 metadata
22 isKyc
23 isArchived
24 rootEntityId
25 status
26 entities {
27 id
28 info
29 idMonitoring
30 dataRequestInfo
31 createdBy
32 entityChecks {
33 id
34 type
35 status
36 result
37 dataRequestInfo
38 dataRequestId
39 folderId
40 comment
41 input
42 createdAt
43 updatedAt
44 expiredAt
45 createdBy
46 }
47 createdAt
48 updatedAt
49 }
50 createdAt
51 updatedAt
52 comments {
53 id
54 createdAt
55 body
56
57
58 name
59 }
60 folderOnboardingLink
61 }
62}
Variables example
1{
2 "folderId": "7aafc693-c27f-4dd6-a5d1-93fe30f4f8fd"
3}
Object types and field descriptions
Entity checks
To apply additional checks for entities from fast countries or to proceed with checks for entities from slow countries, you must use the
requestEntityChecks
mutation that takes the RequestEntityCheckInput
scalar type as argument. For more details, look at the explanation in the Variables example part.How to get entity check results, for example for AML:
1. When you perform an AML entityCheck, you get a verification ID
2. When there is an update in the verification, the webhook provides your verification ID. Webhooks are described in the section Real-time updates (Webhook)
3. You take this ID and
1. When you perform an AML entityCheck, you get a verification ID
2. When there is an update in the verification, the webhook provides your verification ID. Webhooks are described in the section Real-time updates (Webhook)
3. You take this ID and
query Folder
data by ID.Operation example
1mutation RequestEntityChecks($input: RequestEntityCheckInput!) {
2 requestEntityChecks(input: $input) {
3 id
4 status
5 result
6 dataRequestInfo
7 dataRequestId
8 folderId
9 comment
10 input
11 createdAt
12 updatedAt
13 expiredAt
14 type
15 account {
16 id
17 groupId
18 }
19 }
20}
Variables example
1{
2"input": [
3 {"type": "BUSINESS_INFO",
4 "folderId": "21831f3d-ca25-44a0-9096-f77d34340d1f",
5 "isCorporate": true,
6 "input": {
7 "countryCode": "EE",
8 "name": "Vespia",
9 "registrationCode": "EE102360253"}
10 },
11 {"type": "AML",
12 "entityId": "88e9540e-9e96-419d-9e8f-9670e2a80fd3",
13 "isCorporate": false,
14 "input": {
15 "name": ["Boris", null, "Johnson"],
16 "dob": "06/14/1946",
17 "gender": "male",
18 "country": "UK"}
19 }]}
To pass correctly formatted scalar
RequestEntityCheckInput!
you must use an array containing elements that include1{
2 "type": string!,
3 "folderId": string!,
4 "entityId": string!?,
5 "isCorporate": boolean?,
6 "input": {depends on the type value, see table below}!,
7}
Use the following pairs of corresponding “type” and “input” as arguments
Response example
1{
2 "data": {
3 "requestEntityChecks": [
4 {
5 "id": "abacba50-61e5-4e18-8cc8-da17419c9dcd",
6 "status": "AWAITING_CHECK",
7 "result": null,
8 "dataRequestInfo": null,
9 "dataRequestId": "f261fd1e-8a26-41bb-b70e-5aeefd11b7f5",
10 "folderId": "21831f3d-ca25-44a0-9096-f77d34340d1f",
11 "comment": null,
12 "input": {
13 "name": "Vespia",
14 "countryCode": "EE",
15 "registrationCode": "EE102360253",
16 "account": {
17 "accountId": "0db81655-893e-4cf5-a339-2235b65a1769"
18 },
19 "folderId": "21831f3d-ca25-44a0-9096-f77d34340d1f",
20 "isCorporate": true
21 },
22 "createdAt": "2024-02-23T11:58:29.382Z",
23 "updatedAt": "2024-02-23T11:58:29.382Z",
24 "expiredAt": null,
25 "type": "BUSINESS_INFO",
26 "account": {
27 "id": "0db81655-893e-4cf5-a339-2235b65a1769",
28 "groupId": null
29 }
30 },
31 {
32 "id": "c3a22e14-4cdc-41a9-9856-a8a45fe70f85",
33 "status": "AWAITING_CHECK",
34 "result": null,
35 "dataRequestInfo": null,
36 "dataRequestId": "3abe9135-de87-42c3-ae5c-db93db592dd8",
37 "folderId": "21831f3d-ca25-44a0-9096-f77d34340d1f",
38 "comment": null,
39 "input": {
40 "isCorporate": false,
41 "name": "Boris Johnson",
42 "gender": "male",
43 "dob": "June 19, 1964",
44 "country": "UK"
45 },
46 "createdAt": "2024-02-23T11:58:29.382Z",
47 "updatedAt": "2024-02-23T11:58:29.382Z",
48 "expiredAt": null,
49 "type": "AML",
50 "account": {
51 "id": "0db81655-893e-4cf5-a339-2235b65a1769",
52 "groupId": null
53 }
54 }
55 ]
56 }
57}
AML Monitoring
To enable AML monitoring use mutation
EnableEntityCheckMonitoring
with enableEntityCheckMonitoringId
argument corresponding to the entity check with "type": "AML"
To disable AML monitoring, use
mutation disableEntityCheckMonitoring
using the same argumentPage queries
In some cases, you will need pagination and filtering of data. To do so, use
input: PagedQueryInput type
. Below is an example query to get a list of your verifications i.e. Folders.
Operation example
1query Folders($input: PagedQueryInput) {
2 folders(input: $input) {
3 content {
4 id
5 isKyc
6 name
7 }
8 totalPages
9 totalElements
10 last
11 first
12 size
13 number
14 numberOfElements
15 }
16}
Variables example
1{
2 "input": {
3 "pageRequest": {
4 "page": 2,
5 "size": 10,
6 "sort": [
7 {
8 "direction": "ASC",
9 "field": "Id"
10 }
11 ]
12 },
13 "filter": [
14 {
15 "comparators": [
16 {
17 "field": "isActive",
18 "type": "IS",
19 "value": "true"
20 }
21 ],
22 "operator": "AND"
23 }
24 ]
25 }
26}
Response example
1{
2 "data": {
3 "folders": {
4 "content": [
5 {
6 "id": "08e7b3d9-6eeb-4f39-8844-52f15664f160",
7 "isKyc": false,
8 "name": "Vespia OÜ"
9 },
10 {
11 "id": "e68c6e98-753e-45ed-a91d-4c71d85720b1",
12 "isKyc": false,
13 "name": "Vespia OÜ"
14 },
15 {
16 "id": "ef9104bf-f12e-44b9-bb82-8a190b7dfe9c",
17 "isKyc": false,
18 "name": "Vespia OÜ"
19 },
20 {
21 "id": "75ba70cd-6327-46d5-a509-e1c2b321bd14",
22 "isKyc": false,
23 "name": "Vespia OÜ"
24 },
25 {
26 "id": "273eceba-90b6-427a-9d45-da9984d578a9",
27 "isKyc": false,
28 "name": "Vespia OÜ"
29 }
30 ],
31 "totalPages": 63,
32 "totalElements": 313,
33 "last": false,
34 "first": true,
35 "size": 5,
36 "number": 1,
37 "numberOfElements": 5
38 }
39 }
40}
Input structure, types, and field descriptions
Subscription for real-time information updates (Webhook)
To get access to real-time information updates, we use webhooks. To start using it, you must create a subscription and link it with specific events. This flow is shown in the diagram above.
Please note that you only need to create a subscription once. You do not need to create multiple subscriptions. After creating a subscription as shown below, all the necessary data will be sent to your URL, when events occur.
Diagram
Below is a three-step process (with a sample query and sample input parameters) that will help you subscribe to an event and use the subscription in your project. For example, you can track changes that occur in your checks in a dashboard, and the example below demonstrates this:
1. Let's get the list of events -
query Events
. You need to get the event "id"
with the name "event.verificationView.built"
from the response:Operation example
1query Events($input: PagedQueryInput!) {
2 events(input: $input) {
3 content {
4 id
5 name
6 createdAt
7 updatedAt
8 }
9 }
10}
Variables example
1{
2 "input": {
3 "pageRequest": {
4 "page": 1,
5 "size": 10,
6 "sort": []
7 }
8 }
9}
Output example
1{
2 "data": {
3 "events": {
4 "content": [
5 {
6 "id": "af6918ac-2322-4aba-9341-19e711609289",
7 "name": "event.order.created",
8 "createdAt": "2022-05-17T06:51:45.317Z",
9 "updatedAt": "2022-05-17T06:51:45.317Z"
10 },
11 {
12 "id": "060756a2-0843-404f-96de-7ff48933ed16",
13 "name": "event.verificationView.built",
14 "createdAt": "2022-05-17T06:51:45.317Z",
15 "updatedAt": "2022-05-17T06:51:45.317Z"
16 },
17 {
18 "id": "766f5720-b995-4dfd-95c2-0e4e5d20a03a",
19 "name": "event.wallet.updated",
20 "createdAt": "2022-05-17T06:51:45.317Z",
21 "updatedAt": "2022-05-17T06:51:45.317Z"
22 }
23 ]
24 }
25 }
26}
2. Create subscription -
You need to pass your URL as an input parameter, to which our server will automatically send HTTP POST requests.
From the response, you need to get the
mutation CreateWebhookSubscription
. By default, the subscription is activated immediately after creation.You need to pass your URL as an input parameter, to which our server will automatically send HTTP POST requests.
From the response, you need to get the
"id"
of the createWebhookSubscription.Operation example
1mutation CreateWebhookSubscription($input: CreateWebhookSubscriptionInput!) {
2 createWebhookSubscription(input: $input) {
3 id
4 url
5 isActive
6 events {
7 id
8 name
9 createdAt
10 updatedAt
11 }
12 createdAt
13 updatedAt
14 }
15}
Variables example
1{
2 "input": {
3 "url": "https://yourdomain.com/webhook-endpoint"
4 }
5}
Output example
1{
2 "data": {
3 "createWebhookSubscription": {
4 "id": "9e3a7978-1040-49c3-979f-6485986779f2",
5 "url": "https://vespia-webhook-url.com",
6 "isActive": true,
7 "events": [],
8 "createdAt": "2025-01-02T14:31:17.299Z",
9 "updatedAt": "2025-01-02T14:31:17.299Z"
10 }
11 }
12}
3. In the input parameters, we specify both identifiers obtained in the first and second steps, which we assign to the property names accordingly -
"eventId"
and "subscriptionId"
Operation example
1mutation SubscribeOnEvent($input: SubscribeOnEventInput!) {
2 subscribeOnEvent(input: $input) {
3 id
4 url
5 isActive
6 events {
7 id
8 name
9 createdAt
10 updatedAt
11 }
12 }
13}
Variables example
1{
2 "input": {
3 "subscriptionId": "9e3a7978-1040-49c3-979f-6485986779f2",
4 "eventId": "060756a2-0843-404f-96de-7ff48933ed16"
5 }
6}
Example of deactivating a subscription
In the input parameter, you must pass the subscription
"id"
that was created earlier in the first step.Operation example
1mutation DeactivateWebhookSubscription($deactivateWebhookSubscriptionId: UUID!) {
2 deactivateWebhookSubscription(id: $deactivateWebhookSubscriptionId) {
3 id
4 url
5 isActive
6 events {
7 id
8 name
9 createdAt
10 updatedAt
11 }
12 createdAt
13 updatedAt
14 }
15}
Variables example
1{
2 "deactivateWebhookSubscriptionId": "0a68dc26-1afb-4dd1-ba64-3a196321cf41"
3}
There are 3 events available currently:
event.order.created
event.verificationView.built
- fires when there are updates in the folder.event.wallet.updated
- fires when the wallet is updatedTo get an actual list of events and their IDs use query Events
There are 3 events To manage subscriptions, use the following
mutations
: