Admin Users

Admin Users are the operational team that you give access to manage your platform, who have access to the Difitek Back Office.

In the database model, Admin Users are Users whose is_admin flag is set to true.

Admin Users are able to act as normal Users on your front-end, so they can use their same profile to create Offerings or Investments as if they were a non-Admin User.

Admin Users also have certain additional privileges to access data through the Difitek API. For instance, the GET /offerings function only returns Offerings that are Published, Closing or Settled when logged in as a normal, non-Admin User. When logged in as an Admin User, the same function will return all Offerings, including those that have Draft lifecycle status.

Similarly calling GET /offerings/{offering_id} for an Offering whose life_cycle_stage is Draft will return 'Not Found' for non-Admin Users but it will return the Offering's data for Admin Users.

This allows Admin Users to see how an Offering will appear to your Users on your front-end when screening the Offering before it is published and visible to non-Admin Users.

When you create your Network by signing up for developer access, the email address and password that you provide are used to register a new Admin User for your Network. Get in touch with Difitek to add more Admin Users to your account or to enable or disable the is_admin flag for any User in your Network.


A common approach to building up a fintech application's User base is to work with 'affiliates', which are individuals or organizations that recommend new Users to your platform. The affiliates system in the Difitek back-end allows you to keep track of which new Users were recommended by a given affiliate source.

Each User has an affiliate_code attribute and a referral_code attribute, which are both optional. Use affiliate_code to store the code that should be given out by the affiliate User and used by new Users when they join your platform. Use referral_code to save an affiliate code given to a User as they sign up. Therefore a new User A will be considered to have been referred to your platform by User B if User A's referral_code is equal to User B's affiliate_code.

A User's affiliate activity can then be tracked through the Difitek Back Office by clicking on the 'User Affiliate Activity' option from the Users page, which will show a list of all Users who were recommended and a list of their Investments, in case you wish to set up any kind of commission arrangement with your affiliate Users.

One common use case of the affiliates system is to allow Brokers to onboard their existing investor bases to allow them to invest through your platform, whilst keeping track of their investment activities using the Users' referral_code attributes.

API Exceptions

The Difitek API makes extensive use of HTTP Status Codes and exceptions in order to help you handle various types of User error on your front-end. In general the API will always return one of the following HTTP Status Codes:

  • 200 (successful response)
  • 4xx (failed due to client error)
  • 5xx (failed due to a service being unavailable)

API responses showing an HTTP Status Code of 200 indicate that the API request has been processed successfully. Responses in the 4xx range indicate that the API is operating successfully but for some reason the server has not processed the request. A 5xx response means that the API is not responding correctly, and if you see such a response please get in touch with the Difitek support team to let us know.

The most common 4xx responses used by the Difitek API are:

  • 400 Bad Request - e.g. if a request's body is badly formed JSON
  • 401 Unauthorized - e.g. if the request does not have a valid cv-auth header
  • 403 Forbidden - e.g. if the request is made on behalf of a User who does not have permission to perform a certain action, such as editing another User's investment
  • 404 Not Found - e.g. if the request is trying to retrieve data about an object by its id when no such object exists in the database
  • 405 Method Not Allowed - e.g. if the request is a PUT call when the API only supports GET, PATCH, POST and DELETE
  • 409 Conflict - e.g. if a User is trying to make an Investment that contravenes the Offering's investment rules
  • 415 Unsupported Media Type - e.g. if a User is trying to upload an unsupported file to Difitek's Content Delivery Network

In addition to the HTTP Status Codes shown in the status field and 'success' or 'failure' strings provided in the outcome field, every API Exception also returns:

  • code - a unique exception reference number for this exception
  • user_message - a user-friendly message that you may display to Users on your front-end by default (although of course you are free to display your own custom error message to Users if you would prefer)
  • developer_message - a longer-form message that should not be shown to Users but may help your development team to debug the front-end application

When implementing your front-end, you should take into account as many exceptions as you expect your Users to encounter, especially when they concern critical processes such as making an Investment or adding funds to a Wallet.

Blocking Users

Blocking a User means that the User will no longer be able to log in to your platform. If the User tries to authenticate with the API then it will return an exception indicating that the User does not currently have access to the platform.

Users can be blocked from using your platform in two ways: automatically through the API by implementing POST /self/blockUser based on some activities on your front-end or through the Difitek Back Office.

An example of a scenario in which you may wish to call the 'block user' function automatically from the front-end is if your User has failed part of your registration process, such as getting a 'FAIL' response from a third-party KYC/AML service or perhaps failing an investor appropriateness quiz.

Users can be blocked indefinitely or for a set time-period such as 30 days. If they are blocked for a set time-period then they will automatically be unblocked after that expiry date, and they will then be able to log in and interact normally with your platform.


Please see for more information about Contego services.

Content Delivery Networks

A Content Delivery Network (CDN) is an online storage facility for your documents.

When using Difitek's CDN through the Back Office, set the Document's source_type attribute to 0 so that when you retrieve the Document later its url will be automatically signed with Difitek's CDN credentials, which will allow you to access the Document for a short period of time.

When using your own CDN through the API then set the Document's source_type to 1 so that you retrieve the plain url from the Difitek database and then add your own access credentials if required.

All Documents that are uploaded through the Difitek Back Office application are held in Difitek's CDN, and accessible from the Back Office or through the API. No additional agreement is required to use the Difitek CDN through the Back Office application.

Custom Fields

Custom Fields can be used to extend the native Difitek database model with your own attributes that are required for your preferred object models.

Objects such as Users, Organizations, Offerings and Investments can use any number of custom fields in addition to the native fields that are provided by the Difitek database.

To create a new custom field through the API you can use the relevant PATCH function to set a value for a new field by providing the field name and its value in a JSON array. For instance, to create a new custom field for the logged-in User called investor_type with a value of High Net Worth Individual you would implement PATCH /self with request body:

{ "custom" : { "investor_type" : "High Net Worth Individual" } }

Then when you call GET /self the data response will include your new investor_type attribute in the User's custom data array.

By default there is a limit of the number of custom fields available per object in the sandbox environment. If you come across an API exception that indicates that you have reached your limit of custom fields then get in touch with the Difitek support team in order to raise your limit.

Data Models

Through the Back Office or the Admin API it is possible to create and store a structure for your platform's custom fields for Users, Organizations, Offerings and Investments.

Note that the creation of Data Model objects is not required in order to use the custom attribute of any object: Data Models are designed to be no more than helpers for non-technical users of the Back Office, so that they can be guided when entering data that are not part of the Difitek native object data model.

Deal Rooms

A Deal Room is a collection of functionality that can be added to an Offering in order to support a variety of investor due diligence, discussion, communications and task management functions.

An Offering can have any number of Deal Rooms. Typically an Offering would just have one Deal Room if it is used for a due diligence process that is the same for all relevant Users. However, there is no reason why you cannot have several Deal Rooms for a single Offering if you want to have multiple discussion forums or multiple different task lists, with different groups of Users given access to each one.

Deal Rooms can only be accessed by Users who apply to access them and are subsequently granted permission by the manager of the Deal Room. By default the creator of the Deal Room is its only manager. Once other Users have been granted access to the Deal Room, the manager can grant manager access to those Users as well, so that they have management privileges such as approving or rejecting requests to join the Deal Room.

Once a User has been granted access to the Deal Room, they will be able to access a discussion Forum (if you have implemented it on your front-end), create Topics, add a Post to a Topic, and add a Comment to a Post. A User approved to a Deal Room will also be able to respond to due diligence Tasks by marking them as Started or Completed. Such Users can also be granted access to Document Groups in order to view private Documents that are restricted only to Users who are granted access on an individual basis.

Email Verification

The email verification feature allows you to ensure that your Users have a valid email address before allowing them to continue interacting with your platform.

It is an optional feature but it is recommended to prevent your platform from accepting Investments from Users whom you later cannot reach because the email address that they used to register is not correct.

By turning on the 'New User Created' mail trigger in the Difitek Back Office, and creating a mail template that uses the #EMAIL_VERIFY_STRING# keyword, the Difitek Back Office will send an email containing a validation link to all Users at the point that they register on your platform.

By clicking this link, the new User can be taken to a page on your front-end which implements POST /public/verifyEmail, which will set the User's email_verified flag to true.

If the User has email_verified empty or set to false then they have not yet verified their email address, and you can use this flag to redirect them to an email verification page on your front-end as soon as they log in to your platform if you want to force all Users to verify their email address before continuing with your full registration process.

If your User for some reason does not receive the verification email, or it is accidentally sent to their spam folder, you can allow them to re-send the verification email by implementing POST /self/resendVerificationEmail.

If the User has accidentally entered the wrong email when first registering, you can allow them to change their email address by implementing POST /self/changeEmail.

Implementing the Change Email function at any time will reset the User's email_verified flag to false, and it will re-send the verification email to the new email address, so if the User had previously verified an old email address then they will need to verify the new one in order to restore email_verified to true.

Featured Offerings

Offerings can be marked as 'featured' through the Difitek Back Office, meaning that their is_featured flag is set to true.

Featured Offerings are accessible to unauthenticated Users, i.e., Users who have not yet logged in, through the GET /public/featuredOfferings route. They are also accessible through the logged-in equivalent GET /offerings. In both cases, only Offerings that are Published, Closing or Settled will be returned.

Use featured Offerings to display Offerings on pages that are accessible to users before they have logged in, for instance on your homepage.

Note that in some circumstances and in certain regulatory environments, Offerings should not be displayed publicly due to securities promotions restrictions. In those cases, you should require all Users to log in, and perhaps pass an accreditation or KYC/AML process, before allowing them to view the details of any Offerings. In that scenario the Featured Offerings feature would not be used.

Filtering and Sorting

A common requirement when returning lists of data is to return the list in a filtered or sorted format. For instance, on your front-end's Offerings page you may wish to display a list of Offerings by date order or by increasing or decreasing number of investors who have invested in the Offering so far.

Similarly, you may wish to filter the Offerings by their additional_type in order to show your Users the Offerings in their preferred sector or category.

In both of these cases, you should use this format to add filtering or sorting options to the GET request:


GET /.../{endpoint}?orderby={attribute}&sort={asc|desc}


GET /.../{endpoint}?filter[{attribute}][operator]={op}&filter[{attribute}][value]={value}

where {op} can be: = (EQUALS), in (IN ARRAY), > (GREATER THAN) or < (LESS THAN) 


GET /.../{endpoint}?filter[{attribute}][operator]={op}&filter[{attribute}][lower_value]={value}&filter[{attribute}][upper_value]={value}

where {op} is: between (BETWEEN)

For example, to return all Offerings sorted by descending created_at date (i.e., newest first) you would implement:

GET /offerings?orderby=created_at&sort=desc

To return all of the User's Offerings that have greater than 50,000 shares you would implement:

GET /self/offerings?filter[num_of_shares][operator]=>&filter[num_of_shares][value]=50000

To return all of the User's Payouts with a due_date between 1 April 2015 and 31 March 2016 you would implement:

GET /self/payouts?filter[due_date][operator]=between&filter[due_date][lower_value]=2015-04-01&filter[due_date][upper_value]=2016-03-31

To filter using a custom field, prepend custom__ in front of your attribute name. Therefore, to return all Offerings which have

  "custom" : {
    "regulation" : "506c"

you would implement:

GET /offerings?filter[custom__regulation][operator]==&filter[custom__regulation][value]=506c


Please see for more information about GBGroup services.


Please see for more information about GCEN services.

Goji P2P

Please see for more information about Goji P2P services.


Difitek has produced a whitepaper entitled: "Three Approaches to KYC/AML as part of an online Investor Onboarding Process". Please get in touch to request a copy.

Investor Onboarding is the process by which your platform’s Users become acceptable investors or lenders for your operations. Acceptability will depend on your regulatory environment, compliance considerations and your own business requirements and focus.

Running this process efficiently is a critical success factor for any online finance platform, because it takes new Users of your platform from the point at which they are willing to register fully to your service to the point at which they can actively engage with the financing opportunities that you provide.

It is the first significant gate through which your Users must pass in order to start using your full service, and therefore it will have some drop-off rate. This drop-off rate can be measured over time. It will be influenced by many factors, such as your platform’s messaging and positioning, the overall user experience, the segmentation of visitors to the platform, and the amount of information each User is asked to provide.

A high drop-off rate is not necessarily worse than a low one: allowing many Users into your platform might reduce the overall success rate of your other key processes such as matchmaking or closing & settlement; or, more importantly, your platform might not be upholding its compliance and regulatory requirements if it simply approves all Users.

The compliance and regulatory requirements are often grouped together under the general category of Anti-Money Laundering and Know Your Customer (‘AML/KYC’), which typically requires your platform to ensure that none of its Users appear on any Politically Exposed Persons (PEPs) or Sanctions lists.

The Difitek framework facilitates various standard approaches and workflows to KYC/AML as well as providing the flexibility for developers to create their own proprietary process, either by building on top of dozens of integrated third-party services that can support online KYC/AML checks or by integrating new such services by using Difitek’s integration kit.

In this section we illustrate three approaches to KYC/AML as part of your online investor onboarding process, showing in general how each one is implemented using the Difitek framework:

  • Single KYC/AML gate with one provider
  • Multiple KYC/AML gates with one provider
  • Custom KYC/AML workflow with multiple providers

We will not cover topics here relating to ‘enhanced KYC/AML and due diligence’, the management of ongoing compliance, or the maintenance of KYC/AML records. Moreover, this whitepaper does not contain any advice - legal or otherwise - for your compliance requirements, and it should not be read as such. It contains solely guidance on technical process design and implementation.

We start by explaining the typical data that are required for an online data collection process and by sharing some sample screenshots from online finance platforms showing the User’s point of view.

Three Approaches to KYC/AML as part of an online Investor Onboarding Process


The Loanbook object allows for a slightly different investment process, which is common in P2P lending implementations, when compared to the typical structure of creating Investments for an Offering.

When creating an Investment for an Offering, the investor User typically sees a particular Offering that is currently open for investment, and decides to make an Investment into that specific Offering.

Loanbooks, on the other hand, are categories of Offerings that do not represent specific investment opportunities but a set of criteria in which an investor User is interested.

For instance, a Loanbook might be defined as having a term of 3 years and an interest_rate of 6%.

Users can make Investments into a Loanbook to indicate that they would like to invest into anything that falls into that category. Once an Investment is made for a Loanbook, the platform admin team can use the Back Office to make investments from a Loanbook into specific Offerings as and when required by the business. This can also be done automatically as part of an 'automatch' process through the Difitek API.

For example, your platform might run two ongoing Loanbooks: one at an interest rate of 8.5% for up to 24 months with LTV of 85%; and another at an interest rate of 6.5% for up to 24 months with LTV of 65%.

Investors will make investments into one of the Loanbooks and the admin team will track how much funding each Loanbook has received through the Back Office. At the same time, the admin team will be identifying and preparing specific investment opportunities which will be the ultimate target of the Users' funds, and which match the criteria of one of the Loanbooks.

On a regular basis, the admin team might decide to invest from the Loanbook into such an investment opportunity, and at that point the investor User's funds are put to work.

Please get in touch with Difitek to enable Loanbook features for your platform.


Please see for more information about Mangopay services.

Multi-Factor Authentication

Multi-Factor Authentication (MFA) is a method of access control whereby your platform's Users are only able to access your platform after presenting at least two independent pieces of evidence for their identity, typically from the following categories: knowledge (something they know); possession (something they have), and inherence (something they are).

The Difitek back-end supports multi-factor authentication in various ways. All Users are required to provide either an email address and password or social sign-on credentials using a service such as LinkedIn in order to create their account and log in. Either of these counts as single factor authentication, because the User has presented the password (something they know).

You can also request that Users successfully provide a code that is sent to their phone (something they have) via SMS using an integrated service such as Veridu. Such services will update the User's phone_verified attribute to true, which you can then use on your front-end to grant or deny access to the User.

You can require mult-factor authentication as part of the registration process as a one-off or you can request it at any point in your platform's processes, for instance at the point when a User is trying to make an Investment or download a Deal Room Document.

Offering Investment Rules

The Offering object has various attributes that allow you to set hard conditions that will prevent certain Investments from being accepted automatically without needing any kind of manual review or approval process.

If a User tries to make an investment that contravenes any of these rules, the Difitek API will automatically return an Exception, which can then be used to show a message to the User on your front-end.

All of these rules are optional and they are not set by default. If the relevant attribute is set - i.e., contains data - then the rule is considered to be enabled. The data can be set for the Offering through the API or in the Back Office.

  • open_date is a date before which it is not possible to create an Investment
  • close_date is a date after which it is not possible to create an Investment
  • min_commitment is a minimum amount for the Investment's investment_amount. Set this to 1000 to ensure, for example, that all investments are above 1,000 in your currency.
  • max_commitment is a maximum amount for the Investment's investment_amount. Set this to 100000 to ensure, for example, that all investments are below 100,000 in your currency.
  • max_overfunding_amount is the total sum of Investments that will be accepted for an Offering. Set this to the same value as the Offering's funding_goal to prevent any overfunding. Set it to a higher amount to allow overfunding up to that amount. Set it to a lower amount to create several phases of the Investment such that, for example, 50% should be filled first before the remaining 50% can be opened.

Organization Contact Point

The Organization's contact_point attribute holds the id of the User who should be considered the main contact for the Organization. The user_id of an Organization can never be changed: it always holds the id of the User who created the Organization. However, since Users may leave Organizations at any time, the contact_point of an Organization can be updated to a different User.

At the point at which the Organization is created, the User who was logged-in when calling the POST /organizations function is assigned by default as the Organization's contact_point. This User is also the 'author' of the Organization so the User's id will also be saved into the Organization's user_id field.

To update the Organization's contact_point to a different User, you must first add this User to the Organization's team by calling the POST /organizations/{organization_id}/members/{user_id} function. After the User is a member of the Organization, i.e., the User is listed in the Organization's members list, then you can update the Organization's contact_point by using PATCH /organizations/{organization_id} to set the new contact User's id in this field.

If at a later date the contact User leaves the Organization, i.e. you implemented DELETE /organizations/{organization_id}/members/{user_id} to remove that User from the Organization's members list, then the Organization's contact_point will automatically revert to the 'author' of the Organization, i.e. the User whose id is saved in the Organization's user_id field.

Organization Members

When an Organization is first created, it automatically has one member - the User who was logged in when creating the Organization. The Organization's members attribute will contain a list containing just this User. This User is considered to be the 'author' and contact_point of the Organization.

The User can then add other Users to their Organization by implementing POST /organizations/{organization_id}/members/{user_id}.

Any User who is a member of an Organization is considered to have equal privileges its the original author, so Organization members can edit the Organization, view the Organization's Draft Offerings, edit Draft Offerings, create a Deal Room for the Offering, and view any Documents that are attached to the Organization, its Offerings or its Offerings' Deal Rooms.

An Organization member can also remove other Users from the Organization (assuming that this function is available and implemented on your front-end), including the Organization's original author, although if all Users are removed from the Organization then the Organization's contact_point will always revert back to the original author.

The Organization members feature is used in various ways, for instance to show an Organization's fundraising team or to collect various Users together as part of an institutional investment firm. You may also wish to make membership of an Organization a pre-requisite of completing your platform's registration process, by ensuring that the contact_point of some Organization approves a User by accepting their request to join that User's Organization.

Organizations and Offerings

When using the Difitek framework for the first time, one of the most important considerations will be how to represent your platform's particular type of investment activities.

Difitek customers manage investments in many different asset classes: business loans, private securities, real estate investments, P2P lending, equity funding, public/private placements, and many more. In each case the asset needs to be represented in the Difitek data model.

To represent real-life processes as closely as possible, whilst also allowing for the greatest flexibility across different asset classes, Difitek's data model is split into Organizations and Offerings.

An Organization represents the capital raising entity, whether it be a company, a property, a fund, or a project. The Offering represents the activity of raising capital. An Offering must have one and only one Organization. An Organization can have many Offerings, in the case that a company undertakes several capital raises, for example.

When designing your data model, it is recommended to keep this distinction in mind so that the data are held in the most logical place within this structure.

For example, if your Organization will represent a company, then there are certain fields that are independent of the company's current fundraising activities, such as its founding date, its location, or a description of its business practises. By saving these data in the Organization, you can access them once via each of the Organization's Offerings (by looking up the Offering's organization_id) instead of having to copy the same data into each new Offering every time it is created.

Similarly, if you have information that are only relevant to the Organization's current fundraise, such as a current credit score, valuation, or fundraising open date, then store those data in the Offering.

In real estate implementations, it is most common to use the Organization to represent a property fund or an Special Purpose Vehicle (SPV), i.e., the asset in which investor Users will obtain shares (represented by Capitalizations) once the Offering is closed.

In secondary market implementations, it becomes more important to have a single Organization that owns all the secondary Offerings instead of one Organization per Offering, to ensure that the share registry is maintained correctly through the distribution and management of the Organization's Capitalization records.


The Difitek API is designed to support front-end financial services applications that will typically not show more than a number of items that can be displayed on a single page. For example, the usability of a site or application is affected by trying to display too many Offerings, Investments or Payouts on one page without using a user interface element such as a table.

By default, API requests that return lists of items such as GET /offerings or GET self/organizations will return only 12 items.

By specifying a limit parameter you can request more or less than the default number based on the front-end application's design requirements:

GET /offerings?limit=15

This will retrieve the first 15 items from the database. Then to retrieve the second 'batch' of data, specify a page parameter as the offset number of the item from the list:

GET /offerings?limit=15&page=15

This will return the second batch of 15 items from the database (specifying &page=0 would retrieve the page starting with the first item).

These parameters can be used in addition to filtering and sorting parameters, for example, to retrieve the third 10-item page of Organizations sorted by ascending display_name you would request:

GET /organizations?limit=10&page=20&orderby=display_name&sort=asc

Since the API response time will accordingly be slower as the limit parameter is made larger in the request, it is recommended to use pagination wherever possible and to limit the number of items for any single request to a maximum of 20.

Restricted Offerings

Restricted Offerings are Offerings that are only visible to VIP Users, in other words Users who have the is_vip flag set to true. Offerings can be set to the Restricted lifecycle stage through the Back Office application or using PATCH /offerings/{offering_id}.

The purpose of a Restricted Offering is to allow a limited group of your Users to get early access to certain Offerings before they are made generally available to all Users by making them Published.

For instance, you might have a group of power users whom you want to reward by giving them a first chance to see certain Offerings before anyone else. VIP Users can also make Investments for Restricted Offerings before any other non-VIP User gets the chance to see them.

This is not the same as a feature to show Offerings that have not yet opened on an Offering preview page. Under some countries' regulations, it is required to show the details of forthcoming Offerings for a certain time period before the Offering becomes 'Live' such that Users can make Investments for the Offering. To implement this feature, make the Offering Published but use the Offering's open_date attribute to prevent any Investments until the relevant date.

Note that under some financial promotions regulations it is important to give all potential investors equal access to information about an Offering, so get legal advice before using the Restricted Offerings feature if it means that some Users will have preferential access to certain Offering materials.


Please see for more information about Reyker services.

Secondary Markets


Secondary Markets are common to peer-to-peer lending applications and increasingly to equity-based investment platforms, especially in real estate. A platform that operates a Secondary Market gives its Users the opportunity to re-sell their shares, represented by Capitalizations, to other Users on your platform.

Data Model


The ’Organization’ object represents the legal entity or asset in which Users own Capitalizations that can be be split and traded between users.


The Capitalization represents a bucket or batch of shares that are owned by a User. Capitalizations have a life_cycle_stage attribute which is used to track whether the shares are Authorized, Issued or Offered. If a Capitalization is in 'Offered' stage then it can be attached to an Offering in order to be offered on the secondary market.

The Capitalization object ensures that shares cannot be created ex nihilo by creating new secondary Offerings that include a higher number of shares than the User originally acquired through previous Offerings.

Whilst it is in theory possible to operate a simple secondary market without using the Capitalization object, by tracking a chain of primary_offering_id values of each secondary Offering, this leaves open the possibility that mistakes could be made in calculating how many shares are currently held by each User; and it makes it far more difficult to see at a glance the list of shareholders of an Organization.

Furthermore, your platform's admin team can benefit significantly from the Back Office functionality that enables distributing shares from the Offering to the investor Users in a way that ensures that shares are not accidentally lost or counted twice.


The ‘Offering(s)’ are comparable to ‘asks’ in a traditional secondary market, which will consist of a set of Offerings created by users who have a share ownership in the given Organization. Once a platform User decides to sell their shares they will create an Offering which inherits the attributes of the Organization, i.e., the asset, and the Capitalization, i.e., the current value of the shareholding.

The share price or value of the offering can either be set by the seller of shares or the platform operator. It is important that the following attributes are saved for secondary market Offerings:

  • number_of_shares
  • price_per_share

When attaching a Capitalization to an Offering, Users are not be able to input a figure larger than the number_of_shares of the new Offering.

If the User wishes to sell only part of their shares, they should first 'split' their Capitalization into multiple parts and then attach one of the child Capitalizations in whole to the new secondary Offering.


The Investments are comparable to ‘bids’ in a traditional secondary market. The size of the Investment - based on its number_of_shares value not its investment_amount - dictates how much Capitalization will be allocated to the User when the Offering is closed. The creator of the Investment therefore represents the buyer.

An important consideration is to save the number_of_shares into the Investment as well as the investment_amount so that the Back Office Capitalization distribution features can be used.

Using the Secondary Market Statuses

It is important to use the different statuses of objects correctly. The single most important part in this structure is the Investment's Settled / Withdrawn life_cycle_stage, to avoid double ownership in the same asset.


  • Draft: Asset is due to be either published or canceled.
  • Published: Asset is freely tradeable.
  • Canceled: Asset is taken off the marketplace.


  • Authorized: the shares are authorized by the Organization but not yet Issued.
  • Issued: the shares are currently owned and held by the User.
  • Offered: the shares are (or will soon be) attached to an Offering that will be published on your platform and therefore made available to investor Users.


  • Draft: The share offering is due to change status
  • Restricted: The shares are open for investment from VIP users
  • Published: The shares are open for investment
  • Canceled: The share offering is canceled


  • Open: An open bid on the seller's Offering
  • Approved: Bid has been approved by seller and/or admin
  • Rejected: Bid has been rejected by seller and/or admin
  • Withdrawn: the Investment has been canceled
  • Settled: Proof of ownership in asset, settlement has been made

Share Registries

Why this feature is important

A share registry in our system is a list of Users who own shares, represented by the 'Capitalization' object, in an Organization. Many of Difitek's customers, especially those offering their own Organizations or SPVs through their platforms, need to report on this regularly to regulators or auditors.

Our system also provides a complete share valuation history for Users, so that all changes to share prices now feed through to each User’s portfolio, and can be retrieved using GET /self/capitalizations.

Overall, this feature is a way to manage asset value on an Organization (entity / SPV) level rather than Offering by Offering, or Investment by Investment. Using Capitalizations is a much more logical place to keep this data, especially for platforms that manage secondary markets, which would otherwise need to follow multiple chains of Offerings and Investments in order to ascertain the current, final owner of a share.

How do Share Registries interact with Offerings and Investments?

For platforms that use this share registry feature, the Offerings and Investments are a mechanism to move shares from one User to another. They are no longer the ultimate record of a User’s portfolio: they are simply a record of how a transition of shares happened.

The share registry in Difitek's database is managed by an entity called a Capitalization. Capitalizations are ‘owned’ by an Organization, and an Organization can have multiple Capitalizations. A Capitalization is essentially a record of a User holding a certain number of shares of an Organization at a given price.

Each Capitalization has:

  • an Organization;
  • an owner (i.e. the User who currently owns these shares);
  • a Number of Shares, a Price per Share, a Lifecycle Stage;
  • and a Type (Equity or Debt)

It can also be linked to an Offering, if the shares are currently being offered to Users.

The Back Office application enables a process where a Capitalization can be first attached to an Offering and then distributed automatically to all of the Investors of that Offering based on the number of shares they requested, as part of the Closing & Settlement process.

How does it work (non-technical)?

An Organization can issue shares (i.e. create a Capitalization) at any time. Issuing shares does not automatically adjust or dilute existing Capitalizations in the Organization, although those calculations can be made manually and then used to update the Capitalizations individually through the Back Office.

The Lifecycle Stages for a Capitalization are: Authorized -> Issued -> Offered -> Treasury -> Distributed:

  • The Authorized capital of an Organization (sometimes referred to as the authorized share capital, registered capital or nominal capital, particularly in the United States) is the maximum amount of share capital that the Organization is authoriszd by its constitutional documents to issue (allocate) to shareholders.
  • Issued shares is a term of law and finance for the quantity of shares of an Organization, which have been allocated (allotted) and are subsequently held by shareholders. The act of creating new issued shares is called issuance, allocation or allotment.
  • When created, Capitalizations start out as Authorized for Users and then they can be Issued, sometimes gradually over time.
  • When a Capitalization is in Offered stage then it can be attached to an Offering, meaning that it is now ready to be offered to the market.
  • If a Capitalization is in Treasury stage then it’s considered to be owned by the Organization itself in its own treasury rather than by any User, for instance, from a repurchase or buyback from shareholders.
  • A Capitalization in Distributed stage means that it has been superseded by one or more ‘child’ capitalizations, through the Offering->Investment process. The Offering->Investment process cannot create more shares by itself; it only distributes the shares that have been made available. New shares that are distributed by this process are created in Issued state.

As part of the Closing & Settlement process, there is a Back Office function called Distribute Capitalizations.

This process will take the original set of shares that were offered and then distribute them to the Offering’s investors, according to the number of shares that each investor requested when they created an Investment in the Offering.

In this way, at the end of the Offering->Investment process, an Organization will have an up-to-date list of all its shareholders.

Then if any shareholder wishes to put an offering onto the secondary market, they can follow the same process, to distribute some or all of their shares to new investors.

How does it work (technical)?

  1. Go to the Organizations page and find an Organization for which you would like to add a share registry. Press the ‘Capitalizations’ button under the Action column.
  2. Create a new Capitalization, assigning it an Owner, a Number of Shares and a Price per Share. Make the Capitalization 'Offered' so that you can use it in an Offering.
  3. Go to the Offerings page and select 'New Offering'. Select the Organization from the drop-down list, and see that the Capitalization drop-down box updates with a list of Capitalizations that are currently Offered by this Organization. Select the relevant Capitalization, fill in the rest of the Offering's information and press 'Save'. You Offering will now have the Capitalizations attached.
  4. Publish the Offering through the Back Office so that you can start to accept Investments.
  5. Create multiple Investments from multiple Users for this Offering either through the Back Office or through your front-end using the API. Ensure that you specify a number_of_shares for each Investment, since this will be used when distributing the Capitalization later.
  6. Move the Offering to Closing stage from the Offerings page.
  7. Go to Offering's 'Closing & Settlement' page by clicking that option from the Action drop-down menu. You should see a "Distribute Capitalizations" button in the top-right corner.
  8. Settle the Offering, which will then enable the "Distribute Capitalizations" button. The button is disabled if: the Offering is not settled; the Offering does not have an associated Capitalization; or the Capitalization for this Offering has already been "Distributed" (i.e., the Capitalization has a life_cycle_stage = 4).
  9. Click on "Distribute Capitalizations". It will create new Capitalizations for each User that has a settled Investment in this Offering. Upon successful Distribution, the parent Capitalization will have life_cycle_stage = Distributed and its child Capitalizations will have life_cycle_stage = Issued. You will be redirected to the Organization's Capitalizations page to see the updated share registry.
  10. Finally, on your front-end, you can implement a portfolio page using GET /self/capitalizations to show a User their current share portfolio.

P2P lending applications

Although the description has focused on equity share registries, the same process works just the same for loans.

An Organization offering a loan on a P2P marketplace can also create a Capitalization with Type = Debt instead of Equity, and use it to track and distribute loan parts, especially through a secondary market.

The only difference would be that the Number of Shares in a Capitalization would not necessarily be an integer, because a loan can within reason be split into any number of smaller pieces.

Is it necessary to set up Share Registries?

The methodology of simply setting up Offerings and tracking a User’s portfolio through their Investments works perfectly well without ever needing to create a set of Capitalizations to represent an Organization's share registry and then allocate them to investors.

However, we would recommend that platforms managing secondary markets consider implementing the few extra steps in the Back Office to recording share registries as well as Offerings and Investments, in order to ensure that secondary Offerings never get out of sync with the Organization's original share capital, and to improve the performance of your front-end platform, which might otherwise need to cycle iteratively down several chains of Offerings and Investments to find the current owner of any particular share or loan part.

Single Sign On

The Difitek API allows Users to authenticate using an email address and password or through a Single Sign On service such as Facebook, LinkedIn or Twitter.

When authenticating as a User that is not using their email address and password, the cv-auth header must still be generated in the normal way using one of Difitek's SDKs (see except, instead of providing the User's email address and password, set email = social and password = social.

In addition, you must provide an additional header in the API request with:

  • key = jwt-auth
  • value = 'Bearer code'

As an example, your request might have the following headers:

  • cv-auth: AuthToken ApiKey="demo-001", TokenDigest="JgNDOp5I/iU4xsl9P9mRTDE/zTQ=", Nonce="a978bbca17cad3ae915d7c70dac3e406", Created="2016-07-01T18:52:56+00:00", Username="social", Password="FwoOBgAc"
  • jwt-auth: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXUyJ9.eyJleHAiOjE0Njc0ODM5ODYsInVzZXJuYW1lIjoicGF1bGhpZ2dpbnNAY2FudGFiLm5ldCIsImlhdCI6IjE0NjczOTc1ODYifQ.ihFvMob8OG7CKCMV7m-gTvx0M14ZIcCTDpN2VBX4ZuOw43tdEXul0DjZ6u4Uxh6UVXZsEHBtQIRvuMwlDW-ZZ6Y3n8xUvMR5h2tN520gEXAcc3RefVNbQEOrCPX5IHG_Ki02FIQJ0dOJs-OTZs8UZVAo0P9Tqx-W9AgJAZmUGAI

In order to generate the unique code for creating the jwt-auth token, please see the API Documentation for the Social endpoint.

Starter Functions

The 'starter functions' are a collection of 15 of the most common back-ed functions in the Difitek API, which are requied by the majority of different fintech applications.

They include basic functions for registering new Users, logging in, showing a User's account information, showing published Offerings and making an Investment.

As a developer building a platform on top of the Difitek API for the first time, we would suggest reviewing and implementing the starter functions as a first step so that you can cover the basics before moving on to other features that may require slightly more complex user workflows, such as Deal Rooms, Payment Schedules or third party integrated services.

The Investment Lifecycle

The Investment Lifecycle describes the process which Investments follow on the Difitek API.

The processes and rules can be restrictive, especially on the front-end, and they are designed to be so following discussions with financial regulators around the world. For example, it is not possible - even for admin users - to reject an Investment that has previously been Settled, because this would be equivalent to taking an investor's money and accepting a trade of securities, only to decide later that the trade should not be honored.

Similarly, if an Investment has been withdrawn by a User, it cannot be accepted by the admin team.

There are two ways that the lifecycle of Investments can be adjusted: through the API or through the Back Office application. The update rules for each case are as follows.


In the table below, use POST /offerings/{offering_id}/investments where POST is written to create a new Investment in a starting lifecycle stage.

Use DELETE /investments/{investment_id} to move an Investment into a different lifecycle stage where DELETE is written.

Use GET /investments/{investment_id} to retrieve an Investment without updating its lifecycle stage where GET is written.

End Stage-> Open Rejected Approved Withdrawn Settled
Start Stage POST POST
Rejected GET
Withdrawn GET
Settled GET

Back Office

In the table below, use the Back Office features when logged in as an admin user to update the lifecycle stage of another User's Investment.

End Stage-> Open Rejected Approved Withdrawn Settled
Start Stage Create
Open View Reject Approve Settle
Rejected View Approve
Approved Reject View Settle
Withdrawn View
Settled View

The Offering Lifecycle

The Offering Lifecycle describes the process which Offerings follow on the Difitek API.

The processes and rules can be restrictive, especially on the front-end, and they are designed to be so following discussions with financial regulators around the world. For example, it is not possible - even for admin users - to publish an Offering from the front-end, because this might allow your end Users to start promoting securities before the admin team has had chance to verify the offering materials.

Similarly, if an Offering has been Published, it cannot be reset to Draft status by the admin team, to ensure that the information given to potential investor Users on the front-end is consistent for all Users.

There are two ways that the lifecycle of Offerings can be adjusted: through the API or through the Back Office application. The update rules for each case are as follows.


In the table below, use POST /organizations/{organization_id}/offerings where POST is written to create a new Offering in a starting lifecycle stage.

Use PATCH /offerings/{offering_id} to move an Offering into a different lifecycle stage where PATCH is written.

Use DELETE /offerings/{offering_id} to move an Offering into a different lifecycle stage where DELETE is written.

Use GET /offerings/{offering_id} to retrieve an Investment without updating its lifecycle stage where GET is written, for the User's own Offerings. The User is not able to see all Offerings of other Users through this GET function.

End Stage-> Draft Submitted Rejected Approved Restricted Published Closing Settled Canceled
Start Stage POST
Submitted GET DELETE
Restricted GET
Published GET
Closing GET
Settled GET
Canceled GET

Back Office

In the table below, use the Back Office features when logged in as an admin user to update the lifecycle stage of an Offering.

End Stage-> Draft Submitted Rejected Approved Restricted Published Closing Settled Canceled
Start Stage Create
Draft View Update Update Update
Submitted Update View Update Update Update
Rejected Update View Update Update
Approved Update Update View Update Update Update
Restricted View Update Update Update
Published View Update Update
Closing View Update Update
Settled View
Canceled View

Unauthenticated Users

Users of your front-end platform will most likely interact with it once they have logged in so that they can make Investments or submit an Offering for screening. However, you may wish to show some information to website visitors before they log in to your platform. In that case you can work with the API functionality under the /public endpoint, which is designed for unauthenticated Users, i.e., website visitors who have not yet logged in.

Unauthenticated Users will not have a username or password with which to create a cv-auth token, so when implementing any of the /public endpoints you must use username = new and password = new to create an unauthenticated User token with a Difitek SDK. Unauthenticated Users must still use a valid Network Name, API Key and API Secret in order to create a valid unauthenticated User token.

Once you have created such a token, you can implement any of the the /public endpoint features, as well as the POST /users feature, which also requires an unauthenticated User token.

By authenticating with the Difitek API using an unauthenticated User token you can implement Offerings, Organizations and User listings pages on your front-end that are accessible to Users before they log in. However, the majority of the functionality available through Difitek's back-end are restricted to logged-in Users.

User Onboarding

Difitek does not provide any preset User onboarding workflows because every platform is unique and yours will inevitably have its own requirements. Instead, you have various ways to build your own User onboarding process.

Each User has several boolean attributes that are commonly used to represent gates in an onboarding process:

  • email_verified
  • phone_verified
  • term_service_accepted
  • registration_complete
  • has_been_approved
  • has_been_blocked

The email_verified and phone_verified fields can be viewed for a User but cannot be set directly. They are set to false by default and can only be set to true by the User completing a process.

If the User successfully verifies their email address (by clicking a private link in the verification email, taking them to a page on your front-end which correctly implements the POST /public/verifyEmail function) then that User's email_verified attribute will be set to true. This is commonly the very first step in any User onboarding process after the User registers with their email address and password, so a typical implementation of any page on your platform might include a check for email_verified == true just after the User logs in, and if it is false then the User can for instance be redirected to a holding page explaining that the User must verify their email address in order to continue. It is also common to implement POST /self/resendVerificationEmail on this holding page, in case the User cannot find the verification email and wishes it to be resent.

We would recommend enforcing email validation for all of your Users so that in the event that they make investments you have a way of reaching them, which under many regulatory environments is obligatory, for instance to send shareholder certificates or tax statements.

The remaining statuses can be used according to your own platform's business process requirements. Each such status is also visible in the Back Office.

User Password Management

Users can register to your platform using an email address and password or with a third-party authentication account such as LinkedIn.

If your User provides an email address and password then you should simply use that data to create a cv-auth token in order to authenticate using the GET /authenticate API endpoint. You should never store a User's password as plain text in local browser storage, cookies or the User's custom fields.

The Difitek API will never return the User's plain text password and Difitek staff do not have access to your Users' passwords. All passwords are stored encrypted.

You can allow Users to change their password by implementing the POST /self/changePassword function.

VIP Users

VIP Users are Users on your platform whose is_vip flag is set to true. You can grant or revoke VIP status to any User through the Difitek Back Office.

The VIP User feature is typically used to give certain Users early access to Offerings on your platform in conjunction with the Restricted Offerings feature. Offerings whose life_cycle_stage is Restricted can be seen by VIP Users but not by non-VIP Users, making it possible for you either to create a dedicated page on your front-end for VIP Users to view Restricted Offerings or to show additional Offerings to VIP Users on a standard Offerings page, which implements GET /offerings.

Equally, you may use the VIP User feature to create a separate class of User that may have additional privileges unrelated to Offerings, for example you may allow VIP Users to access additional content areas of your front-end platform that are not accessible to non-VIP Users.

Difitek is a trading name of Crowd Valley Inc.

Crowd Valley, Inc does not engage in the offer, sale or transfer of securities and securities may not be offered, sold or transferred via this website. Securities may not be offered or sold in the United States absent (i) registration under the U.S. Securities Act of 1933, as amended (the Securities Act) or (ii) an available exemption from registration under the Securities Act. Please consult legal counsel in the appropriate jurisdiction before offering, selling or buying securities as registration under the Securities Act or similar state legislation may be required.

Please note that the provision of the information on this website does not create and is not intended to create a relationship between Crowd Valley Inc. and any other person. You are not and should not regard yourself as being a client or customer of Crowd Valley Inc. and must not expect Crowd Valley Inc. to have any duties or responsibilities to you, act for you or your clients, or be responsible for providing protections afforded to customers or yourselves or be responsible for advising you in any respect.

Crowd Valley, Inc. Copyright © 2019