Introduction
Welcome to the new version of our API reference. Don't hesitate to share your feedback to tech@hokodo.co
Hokodo provides a simple API to insure invoices against the risk of late or non payment. This API will help you access credit scores and insurance, for multiple use cases, including B2B merchants, B2B marketplaces, and other types of B2B platforms such as accounting, invoicing, CRM, etc.
Hokodo APIs are organized around REST, with predictable, resource-oriented URLs, and use HTTP response codes to indicate API errors.
Our API expects incoming data to be valid JSON objects with requests
containing the header Content-Type: application/json
, unless explicitly stated otherwise.
All responses of the API, including errors, are in JSON, except for some endpoints returning PDF documents, Excel files or CSV files, that will be clearly indicated as such.
You can view request/response examples in the dark area to the right, and you can switch between raw representation and curl command with tabs in the top right.
The base URL of the API in the sandbox (see environments) is https://api-sandbox.hokodo.co/v1/
Authorization
To authentify pass the correct header with each request:
GET /v1/me HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET \
--url https://api-sandbox.hokodo.co/v1/me/ \
--header "Authorization: Token <your_api_key>"
Make sure to replace
<your_api_key>
with your API key from https://sandbox.hokodo.co.
Use your secret key in your API requests. You can manage your keys in your Developer dashboard. Be sure to keep your key secure and do not share it in publicly-accessible areas, such as GitHub, in your client-side Javascript code, etc.
Authorization to the API is done by providing the key in Authorization header
preceded by Token
keyword. The API key can also be provided as user with no
password through HTTP Basic Auth.
All API requests must be made over HTTPS. Calls made over plain HTTP or without proper authentication will fail.
Testing the API
Please make sure to test your integration thoroughly in our sandbox before going live. After registering, you will be given your test API keys. Those are safe to use for development. When you are ready, make sure to replace those keys with live ones.
While testing, the API will not return real pricing and insurance results. If you want to simulate how well we can cover your clients, please do not hesitate to get in touch with our team at partner-support@hokodo.co.
API versioning
The API is in version v1. Your feedback is most appreciated for any improvement.
Backwards compatible changes are made regularly to improve the API. You can find the changelog in the partner dashboard.
Pagination
For example to get 10 transactions starting with the 51st transaction:
GET /v1/transactions/?limit=10&offset=50 HTTP/1.1
curl --request GET \
--url https://api-sandbox.hokodo.co/v1/transactions/?limit=10&offset=50 \
--header "Authorization: Token <your_api_key>"
The answer is a JSON looking like this:
{
"count": 95, # Total number of transactions
"next": "http://api-sandbox.hokodo.co/v1/transactions/?limit=10&offset=60",
"previous": null,
"results": [
{
... # 51st transaction in the list
},
{
... # 52nd transaction in the list
},
...
]
}
The API returns paginated results, for list endpoints where the response might contain many items in a large list. By default, the number of items returned is 25.
You can control the page size and position by using the query parameters
limit
and offset
. limit
controls the number of items displayed, offset
the index of the first item of the list, starting from 0. The defaults if no
value is passed are thus offset=0
and limit=25
.
See examples on the right.
Expansion
For example let's consider the following request:
GET /v1/quotes/quo-kEFDnwu8cnkETeagWAcqF4 HTTP/1.1
curl --request GET \
--url https://api-sandbox.hokodo.co/v1/quotes/quo-kEFDnwu8cnkETeagWAcqF4 \
--header "Authorization: Token <your_api_key>"
It's returning the following JSON response (compacted for the example):
{
"url": "http://api-sandbox.hokodo.co/v1/quotes/quo-kEFDnwu8cnkETeagWAcqF4",
"id": "quo-kEFDnwu8cnkETeagWAcqF4",
"transaction": "trns-TiehJCGZmFRkKoL8NsM3d6",
"client": "co-7QCHuTN5AJycwX7iw9ofW2",
"status": "accepted",
"policy": "pol-EGmUpq4GjeAGJfVXTb2A5Z",
... # Other quote fields
}
We can use
expand=policy,client
for example:
GET /v1/quotes/quo-kEFDnwu8cnkETeagWAcqF4?expand=policy,client HTTP/1.1
curl --request GET \
--url https://api-sandbox.hokodo.co/v1/quotes/quo-kEFDnwu8cnkETeagWAcqF4?expand=policy,client \
--header "Authorization: Token <your_api_key>"
As a response we get:
{
"url": "http://api-sandbox.hokodo.co/v1/quotes/quo-kEFDnwu8cnkETeagWAcqF4",
"id": "quo-kEFDnwu8cnkETeagWAcqF4",
"transaction": "trns-TiehJCGZmFRkKoL8NsM3d6",
"client": {
"url": "https://api-sandbox.hokodo.co/v1/companies/co-7QCHuTN5AJycwX7iw9ofW2",
"id": "co-7QCHuTN5AJycwX7iw9ofW2",
"country": "GB",
"name": "Hokodo Ltd",
"address": "20-22 Wenlock Road, London, England, N1 7GU",
"city": "London",
"postcode": "N1 7GU",
... # Other client field
},
"status": "accepted",
"policy": {
"url": "http://api-sandbox.hokodo.co/v1/policies/pol-EGmUpq4GjeAGJfVXTb2A5Z",
"id": "pol-EGmUpq4GjeAGJfVXTb2A5Z",
"status": "active",
"created": "2018-10-31T10:55:34.580940Z",
"documents": [],
"collection": null
},
... # Other quote fields
}
The API returns some items as API identifiers. The designated resource can be
expanded, meaning that the identifier is replaced in the response with a dictionary
representing the resource itself. You can control which field is expanded using the
query parameter expand
. Expected value is a comma separated list of field names.
Note: At the moment, only read requests can use expansion. You can't use resource expansion for requests where you create and modify resources.
See examples on the right.
Environments
Test environment (aka Sandbox)
Register at: https://sandbox.hokodo.co
API base URL: https://api-sandbox.hokodo.co/v1/
This is the test environment for our API clients, where you can integrate your own software with our API without consequences. It will always run the same version(s), expect the same request format and return the same response format as the production environment.
Data such as prices or underwriting decisions will not be real however, and no insurance is provided. Non-sensitive data, such as companies search, will be as close as possible to the production data.
Production
Apply at: https://www.hokodo.co/contact
API base URL: https://api.hokodo.co/v1/
This is the live, production environment, where:
- the data is real,
- the insurance provided is real and binding for us,
- payments happen and money changes hands (or at least bank accounts).
Data formats
Countries
Requests
- customer countries
GET /v1/countries/customer HTTP/1.1
curl --request GET \
--url https://api-sandbox.hokodo.co/v1/countries/customer
- debtor countries
GET /v1/countries/debtor HTTP/1.1
curl --request GET \
--url https://api-sandbox.hokodo.co/v1/countries/debtor
Response
200 Ok
Content-Type: application/json
[
{
"code": "GB",
"name": "United Kingdom"
},
{
"code": "FR",
"name": "France"
}
]
Where a country input field is required by the API, you can use either the ISO 3166-1 alpha-2 code or the country's name. See below on how to obtain a full list of accepted countries.
- Customer countries:
/v1/countries/customer
Obtain a list of valid countries for a customer.
- Debtor countries:
/v1/countries/debtor
Obtain a list of valid countries for a debtor.
Dates and times
When a date, or date and time field is required by the API, it is expected in ISO 8601 notation, for example:
Type | Format | Example |
---|---|---|
Date | yyyy-mm-dd | 2018-10-31 |
Datetime | yyyy-mm-ddThh:mm:ss.ffffff | 2018-10-31T16:53:00.12345 |
Datetime UTC | yyyy-mm-ddThh:mm:ss.ffffffZ | 2018-10-31T16:53:00.12345Z |
For invoice issue and due dates for example, there is no time associated and the
API expects only a date, no time nor timezone. Be careful if you are internally
converting a datetime with timezone to a date, e.g. 2018-10-31T00:00:00+02:00
could become 2018-10-30T22:00:00Z
when converted to UTC and then 2018-10-30
in the request to the API, which wouldn't fit the user input.
Currencies
When a currency field is used by the API, it is an ISO 4217 code,
such as GBP
, EUR
or USD
.
Decimals
When a money amount is expected or returned by the API, it is a Decimal number presented as a string, e.g. "-50.00". The API usually presents monetary amounts with 2 decimal places, quantities - with 3 decimal places, and other amounts with 6 decimal places.
Companies
Companies register on your platform, and may themselves fill in information about third-party companies. To work with these, we need to properly identify them first.
Companies endpoints
POST /v1/companies/search
GET /v1/companies/<company_id>
Company object
{
"url": "https://api-dev.hokodo.co/v1/companies/co-bqRyKAGaFrEEN8JMjWJiqk",
"id": "co-bqRyKAGaFrEEN8JMjWJiqk",
"name": "Hokodo Ltd",
"creation_date": "2018-02-20",
"status": "Active",
"legal_form": "Private limited with share capital",
"country": "GB",
"address": "35 Kingsland Road, London, E2 8AA",
"city": "London",
"postcode": "E2 8AA",
"email": "",
"phone": "",
"sectors": [
{
"system": "SIC2007",
"code": "64999"
},
{
"system": "SIC2007",
"code": "62012"
},
{
"system": "SIC2007",
"code": "66220"
}
],
"identifiers": [
{
"idtype": "reg_number",
"country": "GB",
"value": "11215527"
}
]
}
field | type | description |
---|---|---|
url | string | API endpoint to access the company |
id | string(uuid) | API unique identifier for the company |
name | string | Company name |
creation_date | date | Date of inception of the company |
status | string | Current status of the company. You are generally interested about Active or ACT companies |
legal_form | string | Legal form of the company. The list of possible legal forms varies from country to country. |
country | country | Registered address: country code |
address | string | Registered address: full postal address |
city | string | Registered address: city name |
postcode | string | Registered address: postcode |
string | Contact email address for the company | |
phone | string | Contact phone number for the company |
sectors | list | The list of sectors the company operate in. |
sectors[*][system] | string | The system of reference to interprete the code (SIC2007 in UK, NAF_2008 in FR) |
sectors[*][code] | string | Sector code in the given system |
identifiers | list | The list of official identifiers know for this company |
identifiers[*][id_type] | string | The type of identifier (reg_number for a registration number, lei for an indentifier of the Global LEI System, vat_number for a tax identifier) |
identifiers[*][country] | country | Country in which the identifier is relevant when it applies. Can be blank. |
identifiers[*][value] | string | Identifier |
Company search
Request
POST /v1/companies/search HTTP/1.1
Content-Type: application/json
{
"name": "Hokodo Ltd",
"country": "GB"
}
curl --request POST \
--url https://api-sandbox.hokodo.co/v1/companies/search \
--header "Content-Type: application/json"
--data-binary "{
\"name\": \"Hokodo Ltd\",
\"country\": \"GB\"
}"
Responses
- regular response
200 OK
Content-Type: application/json
{
"matches": [
{
"url": "https://api-sandbox.hokodo.co/v1/companies/co-EWzoaRqbvsdq8FW7dB6evL",
"id": "co-EWzoaRqbvsdq8FW7dB6evL",
"country": "GB",
"name": "HOKODO LTD",
"address": "35 Kingsland Road, London, United Kingdom, E2 8AA",
"city": "London",
"postcode": "E2 8AA",
"legal_form": "",
"sectors": [],
"creation_date": "2018-02-20",
"identifiers": [
{
"idtype": "reg_number",
"country": "GB",
"value": "11215527"
}
],
"email": "",
"phone": "",
"status": "Undefined",
"confidence": null
},
{
"url": "https://api-sandbox.hokodo.co/v1/companies/co-JbTDrzejAhRafYrKSFEGi4",
"id": "co-JbTDrzejAhRafYrKSFEGi4",
"country": "GB",
"name": "Hokodo Services Ltd",
"address": "35 Kingsland Road, London, E2 8AA",
"city": "London",
"postcode": "E2 8AA",
"legal_form": "Private limited with share capital",
"sectors": [],
"creation_date": "2018-05-09",
"identifiers": [
{
"idtype": "reg_number",
"country": "GB",
"value": "11351988"
}
],
"email": "",
"phone": "",
"status": "Active",
"confidence": null
}
]
}
- no results
200 OK
Content-Type: application/json
{
"matches": []
}
- error response (
country
field missing)
{
"country": [
"This field is required."
]
}
- error response (
name
andreg_number
fields missing)
400 Bad Request
Content-Type: application/json
{
"non_field_errors": [
"Not enough information to identify company. Provide at least country and either name or registration number."
]
}
Search for a company by country, name, registration number if available. Country is mandatory, and one of name or registration number must be provided. The API will try to find the best match and return a list of potential matches.
field | description | requirement |
---|---|---|
country | Country the company is registered in | required |
name | Name of the company | required* |
reg_number | Registration number in country | required* |
(at least one of fields, marked with * is required)
Errors:
code | description |
---|---|
400 | a required field is missing |
View Company
Request
GET /v1/companies/{company_id} HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
curl --request POST \
--url https://api-sandbox.hokodo.co/v1/companies/{company_id} \
--header "Authorization: Token <your_api_key>"
--header "Content-Type: application/json"
Responses
- regular response
200 OK
Content-Type: application/json
{
"url": "https://api-sandbox.hokodo.co/v1/companies/co-EWzoaRqbvsdq8FW7dB6evL",
"id": "co-EWzoaRqbvsdq8FW7dB6evL",
"country": "GB",
"name": "HOKODO LTD",
"address": "35 Kingsland Road, London, United Kingdom, E2 8AA",
"city": "London",
"postcode": "E2 8AA",
"legal_form": "",
"sectors": [],
"creation_date": "2018-02-20",
"identifiers": [
{
"idtype": "reg_number",
"country": "GB",
"value": "11215527"
}
],
"email": "",
"phone": "",
"status": "Undefined",
}
- not found
404 Not Found
Content-Type: application/json
{
"detail": "Not found."
}
Look up a previously found company.
Errors:
code | description |
---|---|
404 | the company_id is probably invalid, and the company has not been found |
Sole traders
By default, only certain types of companies can be insured by Hokodo. Sole traders in the United Kingdom are not registered and found in Companies House's database, and cannot be found in our company search API. They can however be used in the API as creditors, and insured by Hokodo. If a significant portion of your users are sole traders, get in touch with us to enable that function for you.
You will be able to create SoleTrader
objects, which are an extension of the Company
objects. These can be used
as creditors in transactions.
Sole trader endpoints
POST /v1/soletraders
GET /v1/soletraders
GET /v1/soletraders/<soletrader_id>
PATCH /v1/soletraders/<soletrader_id>
SoleTrader object
{
"id": "co-YuNEQ4nqA6Yto9QQUBnopW",
"soletrader_id": "st-eE4un8TnDNjx9Uac2DVa6N",
"owner": "user-sVr7a58Smbfqbo8cVpjEV6",
"unique_id": "0d201ab1-46df-4274-8c90-256eaa66c135"
"vat_number": "15141312",
"trading_name": "The Dogfather 21",
"trading_address": "123 Commercial St, Shoreditch",
"trading_address_city": "London",
"trading_address_postcode": "EC2A 8AB",
"trading_address_country": "GB",
"proprietor_name": "John John",
"proprietor_address_line1": "Flat 5",
"proprietor_address_line2": "10 Residential Street",
"proprietor_address_line3": "Hackney",
"proprietor_address_city": "London",
"proprietor_address_postcode": "EC2 8AA",
"proprietor_address_country": "GB",
"date_of_birth": "1969-12-31"
}
field | type | flags | description |
---|---|---|---|
id | string(uuid) | read-only | Unique company identifier for the object. To be used where a Company identifier is required, such as creditor in a transaction. |
soletrader_id | string(uuid) | read-only | Unique identifier for the object. To be used where a SoleTrader identifier is required. |
owner | string(uuid) | required | Unique identifier of the user associated to the sole trader. |
unique_id | string | required | Unique identifier of the sole trader at your platform |
vat_number | string | optional | VAT number of the sole trader if available. |
trading_name | string | required | Company's name |
trading_address | string | optional | Company's full address |
trading_address_city | string | optional | Company's city |
trading_address_postcode | string | optional | Company's postcode |
trading_address_country | string | optional | Company's country |
proprietor_name | string | required | Proprietor's name |
proprietor_address_line1 | string | optional | Proprietor's address |
proprietor_address_line2 | string | optional | Proprietor's address |
proprietor_address_line3 | string | optional | Proprietor's address |
proprietor_address_city | string | optional | Proprietor's city |
proprietor_address_postcode | string | optional | Proprietor's postcode |
proprietor_address_country | string | required | Proprietor's country |
date_of_birth | string | optional | Proprietor's date of birth (e.g. 1969-12-31 ). Accepted format: YYYY-MM-DD . |
Create a sole trader
Request
POST /v1/soletraders HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"owner": "user-KZcuB2oT6BPTjmQJiHm7ha",
"trading_name": "The Dogfather",
"trading_address": "123 Commercial St, Shoreditch",
"trading_address_city": "London",
"trading_address_postcode": "EC2A 8AB",
"trading_address_country": "GB",
"proprietor_name": "John John",
"proprietor_address_line1": "Flat 5",
"proprietor_address_line2": "10 Residential Street",
"proprietor_address_line3": "Hackney",
"proprietor_address_city": "London",
"proprietor_address_postcode": "EC2 8AA",
"proprietor_address_country": "GB",
"vat_number": "15141312",
"unique_id": "0d201ab1-46df-4274-8c90-256eaa66c136",
"date_of_birth": "1969-12-31"
}
curl --request POST
--url https://api-sandbox.hokodo.co/v1/soletraders \
--header "Authorization: Token <your_api_key>" \
--header 'Content-Type: application/json' \
--data-binary "{
\"owner\": \"user-KZcuB2oT6BPTjmQJiHm7ha\",
\"trading_name\": \"The Dogfather\",
\"trading_address\": \"123 Commercial St, Shoreditch\",
\"trading_address_city\": \"London\",
\"trading_address_postcode\": \"EC2A 8AB\",
\"trading_address_country\": \"GB\",
\"proprietor_name\": \"John John\",
\"proprietor_address_line1\": \"Flat 5\",
\"proprietor_address_line2\": \"10 Residential Street\",
\"proprietor_address_line3\": \"Hackney\",
\"proprietor_address_city\": \"London\",
\"proprietor_address_postcode\": \"EC2 8AA\",
\"proprietor_address_country\": \"GB\",
\"vat_number\": \"15141312\",
\"unique_id\": \"0d201ab1-46df-4274-8c90-256eaa66c136\",
\"date_of_birth\": \"1969-12-31\"
}"
Responses
- regular response
201 Created
Content-Type: application/json
{
"id": "co-5oh3SJKQBaKMov9PYR7BkA",
"owner": "user-mECT3e5n9i7gVGrbn2Pd38",
"soletrader_id": "st-Vdrisa6GZnSp49ZaqMDssR",
"trading_name": "The Dogfather",
"trading_address": "123 Commercial St, Shoreditch",
"trading_address_city": "London",
"trading_address_postcode": "EC2A 8AB",
"trading_address_country": "GB",
"proprietor_name": "John John",
"proprietor_address_line1": "Flat 5",
"proprietor_address_line2": "10 Residential Street",
"proprietor_address_line3": "Hackney",
"proprietor_address_city": "London",
"proprietor_address_postcode": "EC2 8AA",
"proprietor_address_country": "GB",
"vat_number": "15141312",
"unique_id": "0d201ab1-46df-4274-8c90-256eaa66c136",
"date_of_birth": "1969-12-31"
}
- error response (example)
400 Bad Request
Content-Type: application/json
{
"owner": [
"Invalid pk \"user-KZcuB2oT6BPTjmQJiHm7hb\" - object does not exist."
],
"unique_id": [
"sole trader with this Unique identifier on platform already exists."
]
}
To create a sole trader, you create a SoleTrader
object.
Errors
errors | description |
---|---|
400 | a required field is missing or some fields have incorrect values |
List sole traders
Request
POST /v1/soletraders HTTP/1.1
Authorization: Token <your_api_key>
curl --request POST
--url https://api-sandbox.hokodo.co/v1/soletraders \
--header "Authorization: Token <your_api_key>"
Response
200 Ok
Content-Type: application/json
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "co-5oh3SJKQBaKMov9PYR7BkA",
"owner": "user-mECT3e5n9i7gVGrbn2Pd38",
"soletrader_id": "st-Vdrisa6GZnSp49ZaqMDssR",
"trading_name": "The Dogfather",
"trading_address": "123 Commercial St, Shoreditch",
"trading_address_city": "London",
"trading_address_postcode": "EC2A 8AB",
"trading_address_country": "GB",
"proprietor_name": "John John",
"proprietor_address_line1": "Flat 5",
"proprietor_address_line2": "10 Residential Street",
"proprietor_address_line3": "Hackney",
"proprietor_address_city": "London",
"proprietor_address_postcode": "EC2 8AA",
"proprietor_address_country": "GB",
"vat_number": "15141312",
"unique_id": "0d201ab1-46df-4274-8c90-256eaa66c136",
"date_of_birth": "1969-12-31"
}
]
}
List all sole traders, created by your platform
View sole trader
Request
POST /v1/soletraders/<soletrader_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request POST
--url https://api-sandbox.hokodo.co/v1/soletraders/co-5oh3SJKQBaKMov9PYR7BkA \
--header "Authorization: Token <your_api_key>"
Response
200 Ok
Content-Type: application/json
{
"id": "co-5oh3SJKQBaKMov9PYR7BkA",
"owner": "user-mECT3e5n9i7gVGrbn2Pd38",
"soletrader_id": "st-Vdrisa6GZnSp49ZaqMDssR",
"trading_name": "The Dogfather",
"trading_address": "123 Commercial St, Shoreditch",
"trading_address_city": "London",
"trading_address_postcode": "EC2A 8AB",
"trading_address_country": "GB",
"proprietor_name": "John John",
"proprietor_address_line1": "Flat 5",
"proprietor_address_line2": "10 Residential Street",
"proprietor_address_line3": "Hackney",
"proprietor_address_city": "London",
"proprietor_address_postcode": "EC2 8AA",
"proprietor_address_country": "GB",
"vat_number": "15141312",
"unique_id": "0d201ab1-46df-4274-8c90-256eaa66c136",
"date_of_birth": "1969-12-31"
}
Retrieve a single sole trader, created by your platform
Errors
errors | description |
---|---|
404 | the soletrader_id is probably invalid, the sole trader has not been found |
Modify sole trader
Request
PATCH /v1/soletraders/<soletrader_id> HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"trading_name": "The Catfather",
"proprietor_name": "Johnny John"
}
curl --request PATCH
--url https://api-sandbox.hokodo.co/v1/soletraders/co-5oh3SJKQBaKMov9PYR7BkA \
--header "Authorization: Token <your_api_key>" \
--header 'Content-Type: application/json' \
--data-binary "{
\"trading_name\": \"The Catfather\",
\"proprietor_name\": \"Johnny John\"
}"
Response
200 Ok
Content-Type: application/json
{
"id": "co-5oh3SJKQBaKMov9PYR7BkA",
"owner": "user-mECT3e5n9i7gVGrbn2Pd38",
"soletrader_id": "st-Vdrisa6GZnSp49ZaqMDssR",
"trading_name": "The Catfather",
"trading_address": "123 Commercial St, Shoreditch",
"trading_address_city": "London",
"trading_address_postcode": "EC2A 8AB",
"trading_address_country": "GB",
"proprietor_name": "Johnny John",
"proprietor_address_line1": "Flat 5",
"proprietor_address_line2": "10 Residential Street",
"proprietor_address_line3": "Hackney",
"proprietor_address_city": "London",
"proprietor_address_postcode": "EC2 8AA",
"proprietor_address_country": "GB",
"vat_number": "15141312",
"unique_id": "0d201ab1-46df-4274-8c90-256eaa66c136",
"date_of_birth": "1969-12-31"
}
Modify previously created sole trader
Errors
errors | description |
---|---|
404 | the soletrader_id is probably invalid, the sole trader has not been found |
400 | a required field is missing or some fields have incorrect values |
Scores
We compute an internal score to assess risk on companies in order to offer the best insurance prices for your users. We can make internal scores available to you and/or your users to help you better manage credit risk.
Note that all examples in this documentation are for illustration purposes only and do not represent a real risk assessment from Hokodo.
Scores endpoint
POST /v1/scores
Company Score object
{
"company": "co-EWzoaRqbvsdq8FW7dB6evL",
"name": "Hokodo Ltd",
"country": "GB",
"reg_number": "11215527",
"address": "35 Kingsland Road, London, E2 8AA",
"score": "2",
"net_assets": 1780444,
"annualized_turnover": null,
"creation_date": "2018-02-20",
"ultimate_parent_company": "Hokodo Ltd",
"number_officers": 3,
"accounts_next_duedate": "2021-02-28",
"latest_financials_date": "2019-05-31",
"change_net_assets": null,
"change_annualized_turnover": null,
"status": "Active"
}
field | type | description |
---|---|---|
company | string(uuid) | API unique identifier for the company |
name | string | Company name |
reg_number | string | Registration number of the company |
creation_date | date | Date of inception of the company |
status | string | Current status of the company. You are generally interested about Active or ACT companies |
country | country | Registered address: country code |
address | string | Registered address: full postal address |
number_officers | integer | TODO |
ultimate_parent_company | string | Name of the ultimate parent of the current company |
score | string | The actual score value, see below |
net_assets | integer | TODO |
annualized_turnover | integer | TODO |
accounts_next_duedate | date | TODO |
latest_financials_date | date | TODO |
change_net_assets | integer | TODO |
change_annualized_turnover | integer | TODO |
Score value
The score value ranges from 1 to 5 with following indicative meaning:
value | description | recommendation | S&P's equivalent |
---|---|---|---|
"5" | Danger | We do not recommend extending credit terms to this company unless you are really confident that you will get paid. | C-, B- |
"4" | Caution | This firm has a weak credit rating. Manage your exposure to this company carefully. | B, B+ |
"3" | Acceptable | This firm has acceptable financial health, but you should still ensure you can withstand the costs of any default. | BB-, BB+ |
"2" | Fair | This firm has reasonable financial health, though invoice protection can provide additional security. | BBB-, A+ |
"1" | Excellent | This firm has strong financial health. | AA-, AAA |
For partners who have more advanced credit management needs, we can provide more detailed scales upon request.
View Company Score
Requests
- with raw company data
POST /v1/scores HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"name": "Hokodo Ltd.",
"country": "GB"
}
curl --request POST \
--url https://api-sandbox.hokodo.co/v1/scores \
--header "Authorization: Token <your_api_key>"
--header "Content-Type: application/json"
--data-binary "{
\"name\": \"Hokodo Ltd\",
\"country\": \"GB\"
}"
- with identified company
POST /v1/scores HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"company": "co-EWzoaRqbvsdq8FW7dB6evL"
}
curl --request POST \
--url https://api-sandbox.hokodo.co/v1/scores \
--header "Authorization: Token <your_api_key>"
--header "Content-Type: application/json"
--data-binary "{
\"company\": \"co-EWzoaRqbvsdq8FW7dB6evL\"
}"
Responses
- regular response
200 OK
Content-Type: application/json
{
"company": "co-EWzoaRqbvsdq8FW7dB6evL",
"name": "Hokodo Ltd",
"country": "GB",
"reg_number": "11215527",
"address": "35 Kingsland Road, London, E2 8AA",
"score": "2",
"net_assets": 1780444,
"annualized_turnover": null,
"creation_date": "2018-02-20",
"ultimate_parent_company": "Hokodo Ltd",
"number_officers": 3,
"accounts_next_duedate": "2021-02-28",
"latest_financials_date": "2019-05-31",
"change_net_assets": null,
"change_annualized_turnover": null,
"status": "Active"
}
- company does not exist (raw company data)
200 OK
Content-Type: application/json
{
"company": null,
"name": "Non-existent-company",
"country": "GB",
"reg_number": "",
"address": "",
"score": null,
"net_assets": null,
"annualized_turnover": null,
"creation_date": "",
"ultimate_parent_company": "",
"number_officers": null,
"accounts_next_duedate": "",
"latest_financials_date": "",
"change_net_assets": null,
"change_annualized_turnover": null,
"status": ""
}
- company does not exist (with identified company)
400 Bad Request
Content-Type: application/json
{
"company": [
"Invalid pk \"co-EWzoaRqbvsdq8FW7dB6evd\" - object does not exist."
]
}
- error response
400 Bad Request
Content-Type: application/json
{
"company": [
"Bad prefix. Expected a UUID prefixed by \"co\", but got non-existent-company."
]
}
Obtain the score of a single company. The company may have been identified using the search company endpoint beforehand. Otherwise, the API will try and identify the best match based on raw information.
If you choose not to provide company
, you have to specify country
and at least one of name
or reg_number
, just like Company search.
field | description | requirement |
---|---|---|
company | Identifier of the company for which risk is to be evaluated | preferred |
name | Name of the company | optional |
country | Country of the company | optional |
reg_number | Company registration number in the country | optional |
address | Address of the company of the user | optional |
Errors
errors | description |
---|---|
400 | A field is not in the expected format |
Credit limits
This endpoint is in beta with a limited set of partners at the moment. Please let us know if you would like to have access to it.
Depending on the company of the debtor or the creditor, the history of their transactions and repayments, Hokodo can insure their transactions up to a certain credit limit. As a B2B platform using Hokodo, you might want to check whether one of your customers can benefit from Hokodo's insurance, and to know up to which amount.
If your customer is about to complete a transaction, you can use the Transaction endpoint to inform Hokodo about the invoice, and the Quote endpoint to check if it is eligible to insurance.
However, in other situations, your customer may not yet have decided what they want to purchase, but you may wish to proactively know and/or inform them of their eligibility. You may want to know how big of a transaction is insurable for that customer. Or you may want to display that information on your platform. The credit limits endpoints are designed for these situations.
You may do that for example when the customer registers, or when they login, or at regular intervals.
To get the available credit limit for a customer on your platform, please use the following endpoint with the associated customer Company id
POST /credit_limits/debtor/company/<company_id>/
You will get one of the two possible responses:
Eligible: the response will contain several blocks, such as:
- The maximum credit overall that this debtor can have on your platform. This is the largest overall exposure Hokodo will accept to this debtor (including utilised credit).
- The amount of exposure currently utilised for this debtor. In other words it is the sum of the credit exposures Hokodo has already taken on for this debtor via your platform. You can use the first and second responses to communicate a message such as “you are using £XXX out of your £YYY credit limit on our platform".
- The remaining exposure available for this debtor on your platform. This represents the maximum exposure which can still be written for this debtor right now given the other exposures already in place.
Declined: The amount of exposure currently used will be displayed.
Please note that credit limits can evolve over time as new information about the company arises (good or bad), we build a history of orders and repayments with the company, etc.
Note that all examples in this documentation are for illustration purposes only and do not represent a real risk assessment from Hokodo.
Credit limits endpoint
POST /v1/credit_limits/debtor/company/<company_id>/
Credit limit object
{
"company": "co-74cgmhG9U79oTWGEW4jeDW",
"status": "eligible",
"rejection_reason": {
"code": "something-something",
"detail": "An actual sentence",
"params": {
"key": "value"
}
},
"currency": "GBP",
"available_insured_amount": "9876.54",
"current_insured_amount": "1234.56",
"maximum_insured_amount": "11111.10"
}
field | type | description |
---|---|---|
company | string(uuid) | API unique identifier for the company |
status | string | Current credit approval status (eligible or declined ) |
rejection_reason | dictionary | If status is declined , details about why, otherwise null |
currency | currency | ISO 4217 currency code (e.g. GBP , EUR ) |
available_insured_amount | decimal | Credit limit currently available |
current_insured_amount | decimal | Credit limit currently in use |
maximum_insured_amount | decimal | Total credit limit |
Please note that the amounts are given as insurance exposure amounts. If Hokodo covers, for example, 90% of the value of invoices on your platform, then the amounts returned in this endpoint are for the 90% of actually insured value, not for the total amount of invoices.
For example, if the available_insured_amount
is "9,000.00", and the cover
provided by Hokodo is for 90% of the value of invoices, you could give a
customer credit for an invoice up to "10,000.00" in value.
Please also note that in general the maximum_insured_amount
will equal
available_insured_amount
plus current_insured_amount
.
However occasionally this will not be true. The main reason that can happen is that the buyer has other exposures with Hokodo (on other platforms) which have eroded some of his limit on your platform. In general we avoid this scenario by ring-fencing limits for platforms, but occasionally this is not possible (e.g. for buyers with very small limits).
Therefore, it’s best to focus on the available limit and utilisation: you
should display the available_insured_amount
and current_insured_amount
numbers (adjusted for your insured percentage).
Request debtor credit limit
Requests
POST /v1/credit_limits/debtor/company/co-74cgmhG9U79oTWGEW4jeDW/ HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"currency": "GBP"
}
curl --request POST \
--url https://api-sandbox.hokodo.co/v1/credit_limits/debtor/company/co-74cgmhG9U79oTWGEW4jeDW/ \
--header "Authorization: Token <your_api_key>"
--header "Content-Type: application/json"
--data-binary '{
"currency": "GBP"
}'
Responses
- eligible
200 OK
Content-Type: application/json
{
"company": "co-74cgmhG9U79oTWGEW4jeDW",
"status": "eligible",
"rejection_reason": null,
"currency": "GBP",
"available_insured_amount": "9876.54",
"current_insured_amount": "1234.56",
"maximum_insured_amount": "11111.10"
}
- declined
200 OK
Content-Type: application/json
{
"company": "co-74cgmhG9U79oTWGEW4jeDW",
"status": "declined",
"rejection_reason": {
"code": "something-something",
"detail": "An actual sentence",
"params": {
"key": "value"
}
},
"currency": "GBP",
"available_insured_amount": null,
"current_insured_amount": "1234.56",
"maximum_insured_amount": null
}
Request the credit limit for a company, as a debtor (buyer side of the transaction).
The currency is optional in the request, and defaults to EUR
if not provided.
It is advisable to request the credit limit in the currency used by the company in question. For example,
use "currency": "GBP"
when requesting the credit limit of a UK company.
field | description | requirement |
---|---|---|
currency | currency | Desired currency for the credit limit, as a ISO 4217 currency code (e.g. GBP , EUR ) |
Errors
errors | description |
---|---|
400 | A field is not in the expected format |
Legacy users
Your platform can create a user by calling this endpoint. The created user is not yet registered and cannot directly login into our system. However they can register anytime and get access to past transactions and operations associated with them.
A user
is necessary to create transactions and later request an insurance offer. It is associated with a company and other information about the future client, such as their email on the platform, their date of registration on the platform, etc.
To create a legacy user, the associated company
may have been identified using the search company endpoint beforehand or raw data can be provided until user has the opportunity to review.
Legacy user endpoints
POST /v1/users
GET /v1/users
GET /v1/users/<user_id>
PATCH /v1/users/<user_id>
DELETE /v1/users/<user_id>
Legacy user object
{
"id": "user-mECT3e5n9i7gVGrbn2Pd38",
"email": "johnny@hokodo.co",
"unique_id": "",
"has_password": false,
"name": "John",
"phone": "",
"registered": "2017-06-01T14:37:12Z",
"country": "GB",
"company": null,
"company_address": "",
"company_country": "GB",
"company_name": "Hokodo Ltd",
"company_regnum": ""
}
field | type | description |
---|---|---|
id | string(uuid) | API unique identifier for the user |
string | Email of the user | |
unique_id | string | Unique identifier of the user on your platform (currently we don't validate its uniqueness and store it for your reference only) |
has_password | boolean | Describes whether the user has registered with Hokodo and created a password |
name | string | Full name of the user |
phone | string | Phone of the user |
registered | datetime | Date of user registration on your platform |
country | country | Country of the user |
company_name | string | Name of the company |
company_address | string | Address of the company |
company_country | country | Country of the company |
company_regnum | string | Registration number of the company |
Note that registered
is the user's registration date on your platform, not in Hokodo.
Create a legacy user
Request
POST /v1/users HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"name": "John",
"email": "johnny@hokodo.co",
"company_name": "Hokodo Ltd",
"company_country": "GB",
"registered": "2017-06-01T14:37:12Z",
"client_type": "free"
}
curl --request POST \
--url https://api-sandbox.hokodo.co/v1/users \
--header "Authorization: Token <your_api_key>"
--header "Content-Type: application/json"
--data-binary="{
\"name\": \"John\",
\"email\": \"johnny@hokodo.co\",
\"company_name\": \"Hokodo Ltd\",
\"company_country\": \"GB\",
\"registered\": \"2017-06-01T14:37:12Z\",
\"client_type\": \"free\"
}"
Response
- regular response
201 Created
Content-Type: application/json
{
"id": "user-mECT3e5n9i7gVGrbn2Pd38",
"email": "johnny@hokodo.co",
"unique_id": "",
"has_password": false,
"name": "John",
"phone": "",
"registered": "2017-06-01T14:37:12Z",
"country": "GB",
"company": null,
"company_address": "",
"company_country": "GB",
"company_name": "Hokodo Ltd",
"company_regnum": ""
}
- error response
400 Bad Request
Content-Type: application/json
{
"email": [
"This field is required."
],
"name": [
"This field is required."
],
"registered": [
"This field is required."
]
}
The user's name, email and registration date on your platform must be provided. If the company has been identified, you can directly provide its identifier. Otherwise, you may simply fill as much as possible of the raw information (name, country, regnum, address).
field | description | requirement |
---|---|---|
name | Full name of user | required |
Email address of the user | required | |
registered | Registration date on your platform | required |
plan_type | Type of plan (free, paying, premium) | deprecated |
phone | Phone number of user | optional |
unique_id | Unique identifier of the user on your platform | optional |
country | Country of the user | optional |
company | Identifier of the company of the user | preferred |
company_name | Name of the company of the user | optional |
company_country | Country of the company of the user | optional |
company_regnum | Company registration number in the country | optional |
company_address | Address of the company of the user | optional |
Notes:
Repeated
POST
requests with user information that contains the same email address will trigger partial updates on the existing user.Creating a user with this endpoint does not grant the user full access to Hokodo resources. They are still expected to perform self-registration via our Customer portal and set up their credentials.
Errors
errors | description |
---|---|
400 | a required field is missing or some fields have incorrect values |
List legacy users
Request
GET /v1/users HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET \
--url https://api-sandbox.hokodo.co/v1/users \
--header "Authorization: Token <your_api_key>"
Response
200 OK
Content-Type: application/json
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "user-mECT3e5n9i7gVGrbn2Pd38",
"email": "johnny@hokodo.co",
"unique_id": "",
"has_password": false,
"name": "John",
"phone": "",
"registered": "2017-06-01T14:37:10Z",
"country": "GB",
"company": null,
"company_address": "",
"company_country": "GB",
"company_name": "Hokodo Lt",
"company_regnum": ""
}
]
}
You can list all users associated with your platform.
Get legacy user
Request
GET /v1/users/<user_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET \
--url https://api-sandbox.hokodo.co/v1/users/user-mECT3e5n9i7gVGrbn2Pd38 \
--header "Authorization: Token <your_api_key>"
Response
- regular response
200 OK
Content-Type: application/json
{
"id": "user-mECT3e5n9i7gVGrbn2Pd38",
"email": "johnny@hokodo.co",
"unique_id": "",
"has_password": false,
"name": "John",
"phone": "",
"registered": "2017-06-01T14:37:10Z",
"country": "GB",
"company": null,
"company_address": "",
"company_country": "GB",
"company_name": "Hokodo Lt",
"company_regnum": ""
}
- user not found
404 Not Found
Content-Type: application/json
{
"detail": "Not found."
}
Retrieve a previously created user.
Errors
errors | description |
---|---|
404 | the user_id is probably invalid, the user has not been found |
Modify legacy user
TODO: We need to merge contorta!250 for his part to work
Delete legacy user
Request
DELETE /v1/users/<user_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request DELETE \
--url https://api-sandbox.hokodo.co/v1/users/user-mECT3e5n9i7gVGrbn2Pd38 \
--header "Authorization: Token <your_api_key>"
Response
- regular response
204 No Content
- user not found
404 Not Found
Content-Type: application/json
{
"detail": "Not found."
}
Delete a previously created user.
Errors
errors | description |
---|---|
404 | the user_id is probably invalid, the user has not been found |
Organisations
The concept of organisation was introduced to enable grouping of users, as well as facilitate ownership of transactions by organisation entities. If you do not have organisations with multiple users or users with multiple organisations on your platform, you can omit the level of organisations and work with users directly.
Organisation concept
If the organisations functionality is enabled, an organisation can become a transaction's owner. Users can also be labelled as members of an organisation, with different roles and permissions. Note that one user can be part of multiple organisations.
Users in the same organisation will be able to see the same invoices, company matching etc. Depending on their role inside the organisation, they will be able to edit objects linked to the organisation.
Consider the following example:
Charlie, Bob, and Alice are members of the organisation "Test Ltd" from the "Cash flow for SMEs" platform.
When an invoice is synced with the Hokodo API by the "Cash flow for SMEs" platform, when a quote is made, when a customer name is matched to a company, etc., all this applies at the organisation level. It is shared between all the members of the organisation.
At the same time, Charlie and Bob can be members of "Test Plus Ltd", and they will be able to match customer names to companies, add invoices, request quotes etc. together under the name of the new organisation, while Alice will not have access to it.
This is a typical API flow to use organisations:
- create Organisation linked to a Company
- create User A attached to that Organisation
- create User B attached to that Organisation
- create User C attached to that Organisation
- ...
- create Transaction (invoice) attached to that Organisation
- match company from that invoice
- offer a quote
- ...
- all users A, B, C... from the organisation have access to their insurance on Hokodo's customer portal
User roles within organisations
Users can have one of the following roles in an organisation:
read-only
user can only see resources (transactions, quotes and policies) attached to the organisation.member
has the rights of a read-only user and can also edit transactions, get quotes and pay for policies.admin
has the rights of a member user and can also add members, remove members, or change role of members. of the organisation.
Organisation endpoints
POST /v1/organisations
GET /v1/organisations
GET /v1/organisations/<organisation_id>
PATCH /v1/organisations/<organisation_id>
DELETE /v1/organisations/<organisation_id>
Organisation object
{
"id": "org-9RxFsXTgnWqwjK4apxBAn8",
"unique_id": "c105b862-f1ba-4197-9d97-57db63196b00",
"registered": "2017-06-01T14:37:12Z",
"name": "",
"company": null,
"company_name": "Test Ltd",
"company_country": "GB",
"company_regnum": "",
"company_address": "",
"company_postcode": "",
"has_purchased_policy": false,
"users": []
}
field | type | flags | description |
---|---|---|---|
id | string(uuid) | read-only | API unique identifier for the user |
created | datetime | read-only | Created time |
modified | datetime | read-only | Last modified time |
unique_id | string | required | Unique identifier of the organisation on your platform |
registered | datetime | required | When the organisation registered on your platform |
name | string | optional | Organisation name |
company | string | optional | Hokodo unique identifier of the company |
company_name | string | optional | Company name |
company_regnum | string | optional | Company registration number |
company_address | string | optional | Company address |
company_postcode | string | optional | Company postal/zip code |
company_city | string | optional | Company city |
company_country | country | optional | Company country |
has_purchased_policy | boolean | read-only | Indicates whether the organisation has ever purchased any policy |
users | list | read-only | List of users attached to the organisation |
Note that registered
is the organisation's registration date on your platform, not in Hokodo.
Create an organisation
Request
POST /v1/organisations HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"unique_id": "c105b862-f1ba-4197-9d97-57db63196b00",
"registered": "2017-06-01T14:37:12Z",
"name": "My shop",
"company_name": "Test Ltd",
"company_country": "GB"
}
curl --request POST
--url https://api-sandbox.hokodo.co/v1/organisations \
--header "Authorization: Token <your_api_key>" \
--header "Content-Type: application/json" \
--data-binary "{
\"unique_id\": \"c105b862-f1ba-4197-9d97-57db63196b00\",
\"registered\": \"2017-06-01T14:37:12Z"\,
\"name\": \"My shop\",
\"company_name\": \"Test Ltd\",
\"company_country\": \"GB\"
}"
Responses
- organisation created successfully
201 Created
Content-Type: application/json
{
"id": "org-pHr6VCyzQJALUsePkatPBo",
"unique_id": "c105b862-f1ba-4197-9d97-57db63196b00",
"registered": "2017-06-01T14:37:12Z",
"name": "My shop",
"company": null,
"company_name": "Test Ltd",
"company_regnum": "",
"company_address": "",
"company_postcode": "",
"company_city": "",
"company_state": "",
"company_country": "GB",
"has_purchased_policy": false,
"users": []
}
- organisation already exists (identified by
unique_id
), it is updated
200 Ok
Content-Type: application/json
{
"id": "org-pHr6VCyzQJALUsePkatPBo",
"unique_id": "c105b862-f1ba-4197-9d97-57db63196b00",
"registered": "2017-06-01T14:37:12Z",
"name": "My shop",
"company": null,
"company_name": "Test Ltd",
"company_regnum": "",
"company_address": "",
"company_postcode": "",
"company_city": "",
"company_state": "",
"company_country": "GB",
"has_purchased_policy": false,
"users": []
}
To create an organisation, you create an Organisation
object.
Errors
errors | description |
---|---|
400 | a required field is missing or a field has incorrect format |
List organisations
Request
GET /v1/organisations HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET
--url https://api-sandbox.hokodo.co/v1/organisations \
--header "Authorization: Token <your_api_key>"
Response
200 Ok
Content-Type: application/json
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "org-pHr6VCyzQJALUsePkatPBo",
"unique_id": "c105b862-f1ba-4197-9d97-57db63196b00",
"registered": "2017-06-01T14:37:12Z",
"name": "My shop",
"company": null,
"company_name": "Test Ltd",
"company_regnum": "",
"company_address": "",
"company_postcode": "",
"company_city": "",
"company_state": "",
"company_country": "GB",
"has_purchased_policy": false,
"users": []
}
]
}
List organisations created by your platform
View organisation
Request
GET /v1/organisations/<organisation_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET
--url https://api-sandbox.hokodo.co/v1/organisations/org-pHr6VCyzQJALUsePkatPBo \
--header "Authorization: Token <your_api_key>"
Response
200 Ok
Content-Type: application/json
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "org-pHr6VCyzQJALUsePkatPBo",
"unique_id": "c105b862-f1ba-4197-9d97-57db63196b00",
"registered": "2017-06-01T14:37:12Z",
"name": "My shop",
"company": null,
"company_name": "Test Ltd",
"company_regnum": "",
"company_address": "",
"company_postcode": "",
"company_city": "",
"company_state": "",
"company_country": "GB",
"has_purchased_policy": false,
"users": []
}
]
}
Retrieve an organisation created by your platform
Errors
errors | description |
---|---|
404 | the organisation_id is probably invalid, the organisation has not been found |
Modify organisation
Request
PATCH /v1/organisations/<organisation_id> HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"unique_id": "c105b862-f1ba-4197-9d97-57db63196b01",
"registered": "2018-06-01T14:37:12Z",
"company_name": "Another Test Ltd",
"company_country": "FR"
}
curl --request PATCH
--url https://api-sandbox.hokodo.co/v1/organisations/org-pHr6VCyzQJALUsePkatPBo \
--header "Authorization: Token <your_api_key>" \
--header "Content-Type: application/json" \
--data-binary "{
\"unique_id\": \"c105b862-f1ba-4197-9d97-57db63196b01\",
\"registered\": \"2018-06-01T14:37:12Z"\,
\"company_name\": \"Another Test Ltd\",
\"company_country\": \"FR\"
}"
Response
200 Ok
Content-Type: application/json
{
"id": "org-pHr6VCyzQJALUsePkatPBo",
"unique_id": "c105b862-f1ba-4197-9d97-57db63196b01",
"registered": "2018-06-01T14:37:12Z",
"name": "My shop",
"company": null,
"company_name": "Another Test Ltd",
"company_regnum": "",
"company_address": "",
"company_postcode": "",
"company_city": "",
"company_state": "",
"company_country": "FR",
"has_purchased_policy": false,
"users": []
}
Modify an organisation created by your platform
Errors
errors | description |
---|---|
404 | the organisation_id is probably invalid, the organisation has not been found |
400 | a required field is missing or a field has incorrect format |
Delete an organisation
Request
DELETE /v1/organisations/<organisation_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request DELETE
--url https://api-sandbox.hokodo.co/v1/organisations/org-pHr6VCyzQJALUsePkatPBo \
--header "Authorization: Token <your_api_key>"
Responses
- regular response
204 No Content
- can not delete organisation, it has objects attached
409 Conflict
Content-Type: application/json
{
"detail": "Organisation has undeletable objects attached, it cannot be deleted."
}
Delete an organisation created by your platform. Please note, that you can not delete an organisation that has insurance-related objects attached to it (such as accepted quotes or policies, etc.)
Errors
errors | description |
---|---|
404 | the organisation_id is probably invalid, the organisation has not been found |
409 | an organisation can not be deleted because it has objects attached to it |
Users
Your platform can create a user by calling this endpoint. The created user will not be registered, and will not be able to directly login into our system just yet. However they will be able to register anytime in the future, and get access to past transactions and operations.
Users not linked to an organisation cannot access transactions, request quotes or generate policies. Therefore we suggest creating the organisation first, then create users linked to the organisation with the proper role.
User endpoints
POST /v1/users
GET /v1/users
GET /v1/users/<user_id>
PATCH /v1/users/<user_id>
DELETE /v1/users/<user_id>
User object
{
"id": "user-VG4i93EPLRamVFK6oXpvt9",
"email": "johnny@hokodo.co",
"unique_id": "",
"has_password": false,
"name": "John",
"phone": "",
"registered": "2017-06-01T14:37:12Z",
"organisations": [
{
"id": "org-FEjrdMsmhdNp34HxaZ6n63",
"role": "member"
}
]
}
field | type | flags | description |
---|---|---|---|
id | string(uuid) | read-only | API unique identifier for the user |
string | required | Email of the user | |
unique_id | string | optional | Unique identifier of the user on your platform (currently we don't validate its uniqueness and store it for your reference only) |
has_password | boolean | read-only | True if the user has registered with Hokodo and created a password |
name | string | required | Full name of the user |
phone | string | optional | Phone number of the user |
registered | datetime | required | Date of user registration on your platform |
organisations | list | optional | List of organisations to which the user is linked |
organisations[*][id] | string(uuid) | required | API identifier of the organisation |
organisations[*][role] | role | required | Role of the user in the organisation |
Note that registered
is the user's registration date on your platform, not in Hokodo.
Create a user
Request
POST /v1/users HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"name": "John",
"email": "johnny@hokodo.co",
"registered": "2017-06-01T14:37:12Z",
"organisations": [
{
"id": "org-FEjrdMsmhdNp34HxaZ6n63",
"role": "member"
}
]
}
curl --request POST \
--url https://api-sandbox.hokodo.co/v1/users \
--header "Authorization: Token <your_api_key>"
--header "Content-Type: application/json"
--data-binary="{
\"name\": \"John\",
\"email\": \"johnny@hokodo.co\",
\"registered\": \"2017-06-01T14:37:12Z\",
\"organisations\": [
{
\"id\": \"org-FEjrdMsmhdNp34HxaZ6n63\",
\"role\": \"member\"
}
]
}"
Response
- regular response
201 Created
Content-Type: application/json
{
"id": "user-VG4i93EPLRamVFK6oXpvt9",
"email": "johnny@hokodo.co",
"unique_id": "",
"has_password": false,
"name": "John",
"phone": "",
"registered": "2017-06-01T14:37:12Z",
"organisations": [
{
"id": "org-FEjrdMsmhdNp34HxaZ6n63",
"role": "member"
}
]
}
- error response
400 Bad Request
Content-Type: application/json
{
"email": [
"This field is required."
],
"name": [
"This field is required."
],
"registered": [
"This field is required."
],
"organisations": [
"This field is required."
]
}
To create a user, you create a User
object.
Notes:
Repeated
POST
requests with user information that contains the same email address will trigger partial updates on the existing user. Still, organisations field must be omitted on the repeatedPOST
requests, as it will generate a validation exception:{ "organisations": "You can't set this field for an existing user." }
To gain full access to Hokodo resources the users that were created by a platform are still expected to perform self-registration via our Customer portal and set up their credentials.
errors | description |
---|---|
400 | a required field is missing |
List users
Request
GET /v1/users HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET \
--url https://api-sandbox.hokodo.co/v1/users \
--header "Authorization: Token <your_api_key>"
Response
200 OK
Content-Type: application/json
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "user-mECT3e5n9i7gVGrbn2Pd38",
"email": "johnny@hokodo.co",
"unique_id": "",
"has_password": false,
"name": "John",
"phone": "",
"registered": "2017-06-01T14:37:12Z",
"organisations": [
{
"id": "org-FEjrdMsmhdNp34HxaZ6n63",
"role": "member"
}
]
}
]
}
List all users associated with your platform.
Get user
Request
GET /v1/users/<user_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET \
--url https://api-sandbox.hokodo.co/v1/users/user-mECT3e5n9i7gVGrbn2Pd38 \
--header "Authorization: Token <your_api_key>"
Response
- regular response
200 OK
Content-Type: application/json
{
"id": "user-mECT3e5n9i7gVGrbn2Pd38",
"email": "johnny@hokodo.co",
"unique_id": "",
"has_password": false,
"name": "John",
"phone": "",
"registered": "2017-06-01T14:37:12Z",
"organisations": [
{
"id": "org-FEjrdMsmhdNp34HxaZ6n63",
"role": "member"
}
]
}
- user not found
404 Not Found
Content-Type: application/json
{
"detail": "Not found."
}
Look up a previously created user.
errors | description |
---|---|
404 | the user_id is probably invalid, the user has not been found |
Modify user
Request
PATCH /v1/users/<user_id> HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"id": "user-mECT3e5n9i7gVGrbn2Pd38",
"email": "johnny@hokodo.co",
"unique_id": "some-unique-id",
"name": "Johnny",
"phone": "+1234567890",
"registered": "2018-06-01T14:37:10Z"
}
Response
200 OK
Content-Type: application/json
{
"id": "user-mECT3e5n9i7gVGrbn2Pd38",
"email": "johnny@hokodo.co",
"unique_id": "some-unique-id",
"has_password": false,
"name": "Johnny",
"phone": "+1234567890",
"registered": "2018-06-01T14:37:10Z",
"organisations": [
{
"id": "org-FEjrdMsmhdNp34HxaZ6n63",
"role": "member"
}
]
}
Update a previously created user.
Please note that organisation membership can not be updated via this endpoint.
errors | description |
---|---|
404 | the user_id is probably invalid, the user has not been found |
400 | updating a user failed or some of the fields have incorrect format |
Delete user
Request
DELETE /v1/users/<user_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request DELETE \
--url https://api-sandbox.hokodo.co/v1/users/user-mECT3e5n9i7gVGrbn2Pd38 \
--header "Authorization: Token <your_api_key>"
Response
- regular response
204 No Content
- user not found
404 Not Found
Content-Type: application/json
{
"detail": "Not found."
}
Delete a previously created user.
Errors
errors | description |
---|---|
404 | the user_id is probably invalid, the user has not been found |
Manage organisations of user
If your platform supports multiple organisations per user and you have already created some organisations in our API, you can manage users memberships and roles in various organisations. Please refer to section Organisations regarding creating and managing organisations.
Our API provides two alternative endpoint collections to manage relation between users and organisations. Below is the list of methods from the perspective of a user. For the list of methods from the perspective of an organisation, please refer to section Manage users in organisation
User organisations endpoints
POST /v1/users/<user_id>/organisations
GET /v1/users/<user_id>/organisations
GET /v1/users/<user_id>/organisations/<organisation_id>
PATCH /v1/users/<user_id>/organisations/<organisation_id>
DELETE /v1/users/<user_id>/organisations/<organisation_id>
User organisation object
{
"id": "org-pHr6VCyzQJALUsePkatPBo",
"role": "admin"
}
field | type | flags | description |
---|---|---|---|
id | string(uuid) | required | API unique identifier for the organisation |
role | role | required | Role of the user in the organisation |
Add user to organisation
Request
POST /v1/users/<user_id>/organisations HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"id": "org-pHr6VCyzQJALUsePkatPBo",
"role": "admin"
}
curl --request POST
--url https://api-sandbox.hokodo.co/v1/users/user-mECT3e5n9i7gVGrbn2Pd38/organisations \
--header "Authorization: Token <your_api_key>" \
--header "Content-Type: application/json" \
--data-binary "{
\"id\": \"org-pHr6VCyzQJALUsePkatPBo\",
\"role\": \"admin"\
}'
Responses
- regular response
201 Created
Content-Type: application/json
{
"id": "org-pHr6VCyzQJALUsePkatPBo",
"role": "admin"
}
- user already added to the organisation
200 Ok
Content-Type: application/json
{
"id": "org-pHr6VCyzQJALUsePkatPBo",
"role": "admin"
}
- error (organisation not found and/or incorrect user role)
400 Bad Request
Content-Type: application/json
{
"id": [
"Invalid pk \"org-mECT3e5n9i7gVGrbn2Pd39\" - object does not exist."
],
"role": [
"\"reader\" is not a valid choice."
]
}
Attach existing user to a previously created organisation. When a user is already added to the organisation, but a different role is provided in the request, his existing role will be updated.
To create a user, see the relevant section.
Errors
errors | description |
---|---|
400 | a required field is missing or a field has incorrect format |
View organisations of a user
Request
GET /v1/users/<user_id>/organisations HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET
--url https://api-sandbox.hokodo.co/v1/users/user-mECT3e5n9i7gVGrbn2Pd38/organisations \
--header "Authorization: Token <your_api_key>"
Response
200 Ok
Content-Type: application/json
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "org-pHr6VCyzQJALUsePkatPBo",
"role": "admin"
}
]
}
List all organisations of a user
View individual organisation of user
Request
GET /v1/users/<user_id>/organisations/<organisation_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET
--url https://api-sandbox.hokodo.co/v1/users/user-mECT3e5n9i7gVGrbn2Pd38/organisations/org-pHr6VCyzQJALUsePkatPBo \
--header "Authorization: Token <your_api_key>"
Response
200 Ok
Content-Type: application/json
{
"id": "org-pHr6VCyzQJALUsePkatPBo",
"role": "admin"
}
Retrieve one specific organisation of a user
Errors
errors | description |
---|---|
404 | the organisation_id is probably invalid, the organisation has not been found |
Modify user role in organisation
Request
PATCH /v1/users/<user_id>/organisations/<organisation_id> HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"role": "member"
}
curl --request POST
--url https://api-sandbox.hokodo.co/v1/users/user-mECT3e5n9i7gVGrbn2Pd38/organisations/org-pHr6VCyzQJALUsePkatPBo \
--header "Authorization: Token <your_api_key>" \
--header "Content-Type: application/json" \
--data-binary "{
\"role\": \"member"\
}'
Responses
- regular response
200 Ok
Content-Type: application/json
{
"id": "org-pHr6VCyzQJALUsePkatPBo",
"role": "member"
}
- error (incorrect user role)
400 Bad Request
Content-Type: application/json
{
"role": [
"\"reader\" is not a valid choice."
]
}
Modify the role of the user in a specific organisation
Errors
errors | description |
---|---|
400 | the role field is missing or has incorrect value |
Remove user from organisation
Request
DELETE /v1/users/<user_id>/organisations/<organisation_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request DELETE
--url https://api-sandbox.hokodo.co/v1/users/user-mECT3e5n9i7gVGrbn2Pd38/organisations/org-pHr6VCyzQJALUsePkatPBo \
--header "Authorization: Token <your_api_key>"
Response
204 No Content
Remove the user from a specific organisation
Errors
errors | description |
---|---|
404 | the organisation_id is probably invalid, the organisation has not been found |
Manage users in organisation
Our API provides two alternative endpoint collections to manage relation between users and organisations. Below is the list of methods from the perspective of an organisation. For the list of methods from the perspective of a user, please refer to section Manage organisations of user
Organisation users endpoints
POST /v1/organisations/<organisation_id>/users
GET /v1/organisations/<organisation_id>/users
GET /v1/organisations/<organisation_id>/users/<user_id>
PATCH /v1/organisations/<organisation_id>/users/<user_id>
DELETE /v1/organisations/<organisation_id>/users/<user_id>
Organisation user object
{
"id": "user-mECT3e5n9i7gVGrbn2Pd38",
"email": "johnny@hokodo.co",
"role": "admin"
}
field | type | flags | description |
---|---|---|---|
id | string(uuid) | required | API unique identifier for the user |
string | read-only | Email of the user | |
role | role | required | Role of the user in the organisation |
Add user to organisation
Request
POST /v1/organisations/<organisation_id>/users HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"id": "user-mECT3e5n9i7gVGrbn2Pd38",
"role": "admin"
}
curl --request POST
--url https://api-sandbox.hokodo.co/v1/organisations/org-pHr6VCyzQJALUsePkatPBo/users \
--header "Authorization: Token <your_api_key>" \
--header "Content-Type: application/json" \
--data-binary "{
\"id\": \"user-mECT3e5n9i7gVGrbn2Pd38\",
\"role\": \"admin"\
}'
Responses
- regular response
201 Created
Content-Type: application/json
{
"id": "user-mECT3e5n9i7gVGrbn2Pd38",
"email": "johnny@hokodo.co",
"role": "admin"
}
- user already added to the organisation
200 Ok
Content-Type: application/json
{
"id": "user-mECT3e5n9i7gVGrbn2Pd38",
"email": "johnny@hokodo.co",
"role": "admin"
}
- error (user not found and/or incorrect user role)
400 Bad Request
Content-Type: application/json
{
"id": [
"Invalid pk \"user-mECT3e5n9i7gVGrbn2Pd39\" - object does not exist."
],
"role": [
"\"reader\" is not a valid choice."
]
}
Attach previously created user to the organisation. When a user is already added to the organisation, but a different role is provided in the request, his existing role will be updated.
Users can have one of the following roles in an organisation:
To create a user, see the relevant section.
Errors
errors | description |
---|---|
400 | a required field is missing or a field has incorrect format |
View users of organisation
Request
GET /v1/organisations/<organisation_id>/users HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET
--url https://api-sandbox.hokodo.co/v1/organisations/org-pHr6VCyzQJALUsePkatPBo/users \
--header "Authorization: Token <your_api_key>"
Response
200 Ok
Content-Type: application/json
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "user-mECT3e5n9i7gVGrbn2Pd38",
"email": "johnny@hokodo.co",
"role": "admin"
}
]
}
List all current users of an organisation
View individual user of organisation
Request
GET /v1/organisations/<organisation_id>/users/<user_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET
--url https://api-sandbox.hokodo.co/v1/organisations/org-pHr6VCyzQJALUsePkatPBo/users/user-mECT3e5n9i7gVGrbn2Pd38 \
--header "Authorization: Token <your_api_key>"
Response
200 Ok
Content-Type: application/json
{
"id": "user-mECT3e5n9i7gVGrbn2Pd38",
"email": "johnny@hokodo.co",
"role": "admin"
}
Retrieve one specific user of an organisation
Errors
errors | description |
---|---|
404 | the user_id is probably invalid, the user has not been found |
Modify user role in organisation
Request
PATCH /v1/organisations/<organisation_id>/users/<user_id> HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"role": "member"
}
curl --request POST
--url https://api-sandbox.hokodo.co/v1/organisations/org-pHr6VCyzQJALUsePkatPBo/users/user-mECT3e5n9i7gVGrbn2Pd38 \
--header "Authorization: Token <your_api_key>" \
--header "Content-Type: application/json" \
--data-binary "{
\"role\": \"member"\
}'
Responses
- regular response
200 Ok
Content-Type: application/json
{
"id": "user-mECT3e5n9i7gVGrbn2Pd38",
"email": "johnny@hokodo.co",
"role": "member"
}
- error (incorrect user role)
400 Bad Request
Content-Type: application/json
{
"role": [
"\"reader\" is not a valid choice."
]
}
Modify the role of a specific user in an organisation
Errors
errors | description |
---|---|
400 | the role field is missing or has incorrect value |
Remove user from organisation
Request
DELETE /v1/organisations/<organisation_id>/users/<user_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request DELETE
--url https://api-sandbox.hokodo.co/v1/organisations/org-pHr6VCyzQJALUsePkatPBo/users/user-mECT3e5n9i7gVGrbn2Pd38 \
--header "Authorization: Token <your_api_key>"
Response
204 No Content
Remove one specific user from the organisation
Errors
errors | description |
---|---|
404 | the user_id is probably invalid, the user has not been found |
Transactions
A transaction describes an invoice, or order, or any other form of transaction described on your platform, past or present, closed or ongoing.
You will need to create a transaction, before requesting an insurance quote on it.
In order to be able to provide your customers the most adapted insurance offers, we need to have information about their transaction history on your platform. This helps us assess their credit relationship with their clients, especially for smaller companies, as well as reduce fraud.
To do so, you should create transactions through the API prior to requesting insurance.
Transaction endpoints
POST /v1/transactions
PUT /v1/transactions/<transaction_id>/match_debtor
GET /v1/transactions
GET /v1/transactions/<transaction_id>
PATCH /v1/transactions/<transaction_id>
DELETE /v1/transactions/<transaction_id>
PUT /v1/transactions/<transaction_id>/confirm
PUT /v1/transactions/<transaction_id>/paid
GET /transactions/<transaction_id>/payments
POST /transactions/<transaction_id>/payments
PATCH /v1/transactions/<transaction_id>/amend
Transaction object
{
"url": "https://api-sandbox.hokodo.co/v1/transactions/trns-yQKxbtCg9aTS5JYnsRVA9B",
"id": "trns-yQKxbtCg9aTS5JYnsRVA9B",
"owner": "user-mECT3e5n9i7gVGrbn2Pd38",
"unique_id": "876987-987uinjojna-I8UH98Jnj",
"debtor": "co-AgBGknk7D8KixY2ntbJtmT",
"debtor_name": "",
"debtor_country": "",
"debtor_regnum": "",
"debtor_address": "",
"creditor": "co-K35WAmVFuSo6SCAPrSNdkP",
"creditor_name": "",
"creditor_country": "",
"creditor_regnum": "",
"creditor_address": "",
"status": "pending",
"pay_method": "bank",
"net_amount": "10000.00",
"gross_amount": "12000.00",
"currency": "GBP",
"issue_date": "2018-04-25",
"due_date": "2018-05-21",
"paid_date": null,
"number": "AB2018-123",
"items": [
{
"description": "Super ergonomic chairs",
"quantity": "10.000",
"unit_price": "1000.00"
}
],
"source": null,
"transaction_key": "JqzI0T5W7FFdUODv9vkU2bXOTJyV2kT7-Ku2ESJJKXQ",
"estimated_quote_price": null,
"metadata": null,
"referral_url": "https://sandbox.hokodo.co/?transaction=trns-yQKxbtCg9aTS5JYnsRVA9B&key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"scheduled_payments": [
{
"date": "2018-05-21",
"amount": "12000.00"
}
],
"payments": []
}
field | type | flags | description |
---|---|---|---|
url | string | read-only | API endpoint to access the transaction |
id | string(uuiod) | read-only | API unique identifier for the transaction |
owner | string(uuid) | required | API unique identifier for the owner of the transaction (user or organisation) |
unique_id | string | optional | Unique identifier of the transaction in your platform (currently we don't validate its uniqueness and store it for your reference only, but we may enforce uniqueness in the future) |
debtor | string(uuid) | optional | API unique identifier for the debtor company (can be expanded to a full Company object) |
debtor_name | string | optional | Name of the debtor company (if separately provided at create/update) |
debtor_country | country | optional | Country of the debtor company (if separately provided at create/update) |
debtor_regnum | string | optional | Registration number of the debtor company (if separately provided at create/update) |
debtor_address | string | optional | Address of the debtor company (if separately provided at create/update) |
creditor | string(uuid) | optional | API unique identifier for the creditor company (can be expanded to a full Company object) |
creditor_name | string | optional | Name of the creditor company (if separately provided at create/update) |
creditor_country | country | optional | Country of the creditor company (if separately provided at create/update) |
creditor_regnum | string | optional | Registration number of the creditor company (if separately provided at create/update) |
creditor_address | string | optional | Address of the creditor company (if separately provided at create/update) |
number | string | optional | Transaction number according to the owner's internal numbering system |
status | string | optional | Transaction status |
pay_method | string | optional | Payment method |
net_amount | decimal | optional | Decimal value of the net transaction amount |
gross_amount | decimal | optional | Decimal value of the gross transaction amount |
currency | currency | optional | Currency of transaction amounts |
issue_date | date | optional | Date of issuance of the transaction |
due_date | date | optional | Date due of the transaction |
paid_date | date | optional | Date when the transaction is paid in full |
items | list | optional | The list of items that constitute the transaction |
items[*][decription] | string | required | Description of the item |
items[*][quantity] | decimal | required | Number of items in the transaction |
items[*][unit_price] | decimal | required | Price of a single item |
scheduled_payments | list | optional | The list of partial payments, expected according to a defined schedule |
scheduled_payments[*][date] | string | required | Payment date |
scheduled_payments[*][amount] | decimal | required | Payment amount in transaction currency |
payments | list | optional | The list of partial payments, that have actually been received |
payments[*][id] | string(uuid) | read-only | API unique identifier for the transaction payment |
payments[*][date] | string | required | Payment date |
payments[*][amount] | decimal | required | Payment amount in transaction currency |
policy | string(uuid) | read-only | API unique identifier for the transaction policy (if created, can be expanded to a full Policy object) |
quote | string(uuid) | read-only | API unique identifier for the transaction quote (if created, can be expanded to a full Quote object) |
source | string | read-only | Source of transaction (available if the transaction has been imported from an accounting platform) |
referral_url | string | read-only | A URL for referring the customer to Hokodo Quote&Buy website, see Referral URL |
metadata | dict | optional | Set of key-value pairs you can attach to the object. You can use this to store your custom data in the object and read it back later. |
estimated_quote_price | null | deprecated |
Transaction status
The transaction status
must be one of:
draft
, meaning the invoice is not issued yet, more information belowpending
, meaning the invoice is due and not yet paidpaid
, meaning the invoice is paiddefaulted
, meaning the invoice is overdue and not yet paid
On draft transactions
Draft transaction status can be used for transactions that the user has not yet commited to, eg. they put something in their cart but did not go through with the checkout.
A draft transaction can be updated, like any other uninsured transaction. Its status can only go from draft
to pending
though, and a pending
transaction cannot go back to the draft
status.
An insured transaction cannot be updated. In particular an insured draft transaction cannot be updated via the transaction update API endpoint. The only change you can make to an insured draft transaction is to change its status to pending. See below for more details.
This will change the status of a transaction from draft
to pending
, and works even if the transaction has already been insured.
Payment method
The payment_method
must be one of:
unknown
, when payment method is not determinedbank
, for bank transfercard
, for payment cardcash
, for cash
Create transaction
Requests
- using debtor and creditor, previously identifier by the API
POST /v1/transactions HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"owner": "user-nNqgg5AFymQMumaU7EdrLa",
"debtor": "co-4MRXDjtbScBmDzbrTbh9SW",
"creditor": "co-7QCHuTN5AJycwX7iw9ofW2",
"net_amount": 10000,
"gross_amount": 12000,
"currency": "GBP",
"issue_date": "2018-04-25",
"due_date": "2018-05-21",
"paid_date": "2018-06-10",
"number": "AB2018-123",
"status": "paid",
"pay_method": "bank",
"items": [
{
"description": "Super ergonomic chairs",
"quantity": 10,
"unit_price": 1000
}
],
"unique_id": "876987-987uinjojna-I8UH98Jnj"
}
curl --request POST \
--url https://api-sandbox.hokodo.co/v1/transactions \
--header "Content-Type: application/json" \
--header "Authorization: <your_api_key>" \
--data-binary "{
\"owner\": \"user-nNqgg5AFymQMumaU7EdrLa\",
\"debtor\": \"co-4MRXDjtbScBmDzbrTbh9SW\",
\"creditor\": \"co-7QCHuTN5AJycwX7iw9ofW2\",
\"net_amount\": 10000.000,
\"gross_amount\": 12000.000,
\"currency\": \"GBP\",
\"issue_date\": \"2018-04-25\",
\"due_date\": \"2018-05-21\",
\"paid_date\": \"2018-06-10\",
\"number\": \"AB2018-123\",
\"status\": \"paid\",
\"pay_method\": \"bank\",
\"items\": [
{
\"description\": \"Super ergonomic chairs\",
\"quantity\": 10,
\"unit_price\": 1000
}
],
\"unique_id\": \"876987-987uinjojna-I8UH98Jnj\"
}"
- using debtor and creditor raw information
POST /v1/transactions HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"url": "https://api-sandbox.hokodo.co/v1/transactions/trns-krF9xKJcjC28mKGV2byJof",
"id": "trns-krF9xKJcjC28mKGV2byJof",
"owner": "user-mECT3e5n9i7gVGrbn2Pd38",
"unique_id": "876987-987uinjojna-I8UH98Jnj",
"debtor": null,
"debtor_name": "Debtor Company",
"debtor_country": "GB",
"debtor_regnum": "1234567890",
"debtor_address": "Some existing address",
"creditor": null,
"creditor_name": "Creditor Company",
"creditor_country": "GB",
"creditor_regnum": "9876543210",
"creditor_address": "Some other existing address",
"status": "pending",
"pay_method": "bank",
"net_amount": "10000.00",
"gross_amount": "12000.00",
"currency": "GBP",
"issue_date": "2018-04-25",
"due_date": "2018-05-21",
"paid_date": null,
"number": "AB2018-123",
"items": [
{
"description": "Super ergonomic chairs",
"quantity": "10.000",
"unit_price": "1000.00"
}
],
"source": null,
"transaction_key": "tQ9OhMH-uxIvHswdISDce2sfVxpMRX3eEyx2RXs0YV4",
"estimated_quote_price": null,
"metadata": null,
"scheduled_payments": [],
"payments": []
}
curl --request POST \
--url https://api-sandbox.hokodo.co/v1/transactions \
--header "Content-Type: application/json" \
--header "Authorization: <your_api_key>" \
--data-binary "{
\"owner\": \"user-nNqgg5AFymQMumaU7EdrLa\",
\"debtor_name\": \"Debtor Company\",
\"debtor_country\": \"GB\",
\"debtor_regnum\": \"1234567890\",
\"debtor_address\": \"Some existing address\",
\"creditor_name\": \"Creditor Company\",
\"creditor_country\": \"GB\",
\"creditor_regnum\": \"9876543210\",
\"creditor_address\": \"Some other existing address\",
\"net_amount\": 10000.000,
\"gross_amount\": 12000.000,
\"currency\": \"GBP\",
\"issue_date\": \"2018-04-25\",
\"due_date\": \"2018-05-21\",
\"paid_date\": \"2018-06-10\",
\"number\": \"AB2018-123\",
\"status\": \"paid\",
\"pay_method\": \"bank\",
\"items\": [
{
\"description\": \"Super ergonomic chairs\",
\"quantity\": 10,
\"unit_price\": 1000
}
],
\"unique_id\": \"876987-987uinjojna-I8UH98Jnj\"
}"
Responses
- regular response (debtor and creditor identified by API)
201 Created
Content-Type: application/json
{
"url": "https://api-sandbox.hokodo.co/v1/transactions/trns-yQKxbtCg9aTS5JYnsRVA9B",
"id": "trns-yQKxbtCg9aTS5JYnsRVA9B",
"owner": "user-mECT3e5n9i7gVGrbn2Pd38",
"unique_id": "876987-987uinjojna-I8UH98Jnj",
"debtor": "co-AgBGknk7D8KixY2ntbJtmT",
"debtor_name": "",
"debtor_country": "",
"debtor_regnum": "",
"debtor_address": "",
"creditor": "co-K35WAmVFuSo6SCAPrSNdkP",
"creditor_name": "",
"creditor_country": "",
"creditor_regnum": "",
"creditor_address": "",
"status": "pending",
"pay_method": "bank",
"net_amount": "10000.00",
"gross_amount": "12000.00",
"currency": "GBP",
"issue_date": "2018-04-25",
"due_date": "2018-05-21",
"paid_date": null,
"number": "AB2018-123",
"items": [
{
"description": "Super ergonomic chairs",
"quantity": "10.000",
"unit_price": "1000.00"
}
],
"source": null,
"transaction_key": "JqzI0T5W7FFdUODv9vkU2bXOTJyV2kT7-Ku2ESJJKXQ",
"estimated_quote_price": null,
"metadata": null,
"referral_url": "https://sandbox.hokodo.co/?transaction=trns-yQKxbtCg9aTS5JYnsRVA9B&key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"scheduled_payments": [],
"payments": []
}
- regular response (debtor and creditor not identified by API)
201 Created
Content-Type: application/json
{
"url": "https://api-sandbox.hokodo.co/v1/transactions/trns-yQKxbtCg9aTS5JYnsRVA9B",
"id": "trns-yQKxbtCg9aTS5JYnsRVA9B",
"owner": "user-mECT3e5n9i7gVGrbn2Pd38",
"unique_id": "876987-987uinjojna-I8UH98Jnj",
"debtor": null,
"debtor_name": "Debtor Company",
"debtor_country": "GB",
"debtor_regnum": "1234567890",
"debtor_address": "Some existing address",
"creditor": null,
"creditor_name": "Creditor Company",
"creditor_country": "GB",
"creditor_regnum": "1234567890",
"creditor_address": "Some existing address",
"status": "pending",
"pay_method": "bank",
"net_amount": "10000.00",
"gross_amount": "12000.00",
"currency": "GBP",
"issue_date": "2018-04-25",
"due_date": "2018-05-21",
"paid_date": null,
"number": "AB2018-123",
"items": [
{
"description": "Super ergonomic chairs",
"quantity": "10.000",
"unit_price": "1000.00"
}
],
"source": null,
"transaction_key": "JqzI0T5W7FFdUODv9vkU2bXOTJyV2kT7-Ku2ESJJKXQ",
"estimated_quote_price": null,
"metadata": null,
"referral_url": "https://sandbox.hokodo.co/?transaction=trns-yQKxbtCg9aTS5JYnsRVA9B&key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"scheduled_payments": [],
"payments": []
}
- error response (example)
400 Bad Request
Content-Type: application/json
{
"debtor": [
"Invalid pk \"co-AgBGknk7D8KixY2ntbJtmA\" - object does not exist."
],
"creditor": [
"Bad prefix. Expected a UUID prefixed by \"co\", but got some-company."
]
}
- error response (incorrect owner type)
http-doc 400 Bad Request Content-Type: application/json
json-doc { "owner": [ "Bad prefix. Expected a UUID prefixed by \"org\", but got user-mECT3e5n9i7gVGrbn2Pd38." ] }
To create a transaction, you create a Transaction
object.
Most fields are optional. Only the owner is required. It identifies a user or organisation of the platform to which the transaction is attached.
Many fields are optional. However to obtain a quote later the system must be provided with the following information at least:
- A way to identify the debtor (name or id)
- A way to identify the creditor (name or id)
- The net invoice amount and currency
- The issue date of the invoice
- The payment due date
The more information is provided at transaction creation, the better the quote quality and the less friction for client subscription later on.
The preferred way to identify the debtor is to provide the debtor's API unique identifier in the debtor
field. However, you may use debtor_country
in conjunction with debtor_name
and / or debtor_regnum
to obtain a match later on. These fields behave the same way than a Company search. The same goes for creditor fields.
Errors
errors | description |
---|---|
400 | a required field is missing or some of the fields have incorrect value |
Company matching for existing transactions
Request
PUT /v1/transactions/<transaction_id>/match_debtor HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"debtor": "co-CWzEFpHwrmxx9NWsXXL7u8"
}
curl --request POST
--url https://api-sandbox.hokodo.co/v1/transactions/trns-yQKxbtCg9aTS5JYnsRVA9B"/match-debtor \
--header "Authorization: Token <your_api_key>" \
--header "Content-Type: application/json" \
--data-binary "{
\"debtor\": \"co-CWzEFpHwrmxx9NWsXXL7u8"\
}'
Responses
- regular response
200 Ok
Content-Type: application/json
{
"url": "https://api-sandbox.hokodo.co/v1/transactions/trns-yQKxbtCg9aTS5JYnsRVA9B",
"id": "trns-yQKxbtCg9aTS5JYnsRVA9B",
"owner": "user-mECT3e5n9i7gVGrbn2Pd38",
"unique_id": "876987-987uinjojna-I8UH98Jnj",
"debtor": "co-CWzEFpHwrmxx9NWsXXL7u8",
"debtor_name": "Debtor Company",
"debtor_country": "GB",
"debtor_regnum": "1234567890",
"debtor_address": "Some existing address",
"creditor": null,
"creditor_name": "Creditor Company",
"creditor_country": "GB",
"creditor_regnum": "1234567890",
"creditor_address": "Some existing address",
"status": "pending",
"pay_method": "bank",
"net_amount": "10000.00",
"gross_amount": "12000.00",
"currency": "GBP",
"issue_date": "2018-04-25",
"due_date": "2018-05-21",
"paid_date": null,
"number": "AB2018-123",
"items": [
{
"description": "Super ergonomic chairs",
"quantity": "10.000",
"unit_price": "1000.00"
}
],
"source": null,
"transaction_key": "JqzI0T5W7FFdUODv9vkU2bXOTJyV2kT7-Ku2ESJJKXQ",
"estimated_quote_price": null,
"metadata": null,
"referral_url": "https://sandbox.hokodo.co/?transaction=trns-yQKxbtCg9aTS5JYnsRVA9B&key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"scheduled_payments": [],
"payments": []
}
- error (debtor not found)
400 Bad Request
Content-Type: application/json
{
"debtor": [
"Invalid pk \"co-AgBGknk7D8KixY2ntbJtmd\" - object does not exist."
]
}
When a user fills in details of an invoice, or when importing invoices from an external accounting/invoicing provider, often enough only the name of the debtor is filled in. To provide accurate quotes, we need to match that debtor name to a precise legal entity.
The API provides a number of ways to do that, depending on your use case. The user could be typing a company name every time, or creating companies and typing the name only once, or importing that data from an external accounting package. Here are some options:
When a user types in a company name, always offer a choice of companies to match it, for example a drop down from the result of our company search endpoint, and pass that company API identifier with the invoice.
When a user creates a company and types the name, offer a choice of companies to match it, for example a drop down from the result of our company search endpoint, save that company API identifier and pass it with every invoice later.
Pass the information you have to us (company name, country, address, registration number, etc.) when creating the invoice in the API, without trying to match the company name to the actual company. When you request a quote, we will try to provide it with the best match we found. You can then redirect the user to our quote portal (which can be co-branded). The user will be asked to confirm the match before proceeding to purchase insurance. In this case, we take care of the company matching UX.
In the case a user has to create companies and type their name, or you are importing data from such a system, essentially when you know the name is consistent across invoices, ie "Test customer" will always designate the same company, we provide an endpoint to store this match on our side so you don't have to take care of it. Create the invoices in the API with the information you have (company name, country, address, registration number, etc.). Before offering an insurance quote, make it visible to the user that they need to match the name to an actual company. Once they do that, you can call the match company endpoint described below.
The remaining part of this sub-section describes the latter scenario.
Concepts of company matching
Let's start with an example. The user has to create customers before assigning them to their invoices. To do that, they have to enter their name and country. For example the user creates "Test customer" in the United Kingdom. Every time the user wants to create an invoice to "Test customer", they pick them from a list of options.
Before offering an insurance quote, make it visible to the user that they need to match the name to an actual company. Once they do that, you can inform the API:
- provide the user with a list of choices of possible companies matching the free text they typed
- create a CompanyMatch object that saves this choice
All the transactions of this user that had "Test customer" for debtor name will be automatically updated to point to the correct legal entity, for example "Test Customer LTD". Once the user imports new invoices with the same debtor name, the match will be made automatically as well.
If one of these transactions was already insured, we do not modify it but trigger a warning, to be handled by our customer support.
The CompanyMatch object
field | type | flags | description |
---|---|---|---|
debtor | string(uuid) | required | API unique identifier of the debtor |
Create a match
To create a match, you associate the debtor
of a transaction
to a company identified by its Hokodo API identifier. That identifier can be obtained through the company search endpoint.
Usually, the matching will be done in three steps:
- create an invoice with just the debtor name (see Create transaction)
- search company to provide matches (see Company search)
- save the match (see code example in this section)
List transactions
Request
GET /v1/transactions HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
curl --request GET \
--url https://api-sandbox.hokodo.co/v1/transactions \
--header "Content-Type: application/json" \
--header "Authorization: <your_api_key>"
Response
200 Ok
Content-Type: application/json
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"url": "https://api-sandbox.hokodo.co/v1/transactions/trns-yQKxbtCg9aTS5JYnsRVA9B",
"id": "trns-yQKxbtCg9aTS5JYnsRVA9B",
"owner": "user-mECT3e5n9i7gVGrbn2Pd38",
"unique_id": "876987-987uinjojna-I8UH98Jnj",
"debtor": "co-AgBGknk7D8KixY2ntbJtmT",
"debtor_name": "",
"debtor_country": "",
"debtor_regnum": "",
"debtor_address": "",
"creditor": "co-K35WAmVFuSo6SCAPrSNdkP",
"creditor_name": "",
"creditor_country": "",
"creditor_regnum": "",
"creditor_address": "",
"status": "pending",
"pay_method": "bank",
"net_amount": "10000.00",
"gross_amount": "12000.00",
"currency": "GBP",
"issue_date": "2018-04-25",
"due_date": "2018-05-21",
"paid_date": null,
"number": "AB2018-123",
"items": [
{
"description": "Super ergonomic chairs",
"quantity": "10.000",
"unit_price": "1000.00"
}
],
"source": null,
"policy": null,
"quote": null,
"estimated_quote_price": null,
"metadata": null,
"referral_url": "https://sandbox.hokodo.co/?transaction=trns-yQKxbtCg9aTS5JYnsRVA9B&key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"scheduled_payments": [],
"payments": []
},
{
"url": "https://api-sandbox.hokodo.co/v1/transactions/trns-krF9xKJcjC28mKGV2byJof",
"id": "trns-krF9xKJcjC28mKGV2byJof",
"owner": "user-mECT3e5n9i7gVGrbn2Pd38",
"unique_id": "876987-987uinjojna-I8UH98Jnj",
"debtor": null,
"debtor_name": "Debtor Company",
"debtor_country": "GB",
"debtor_regnum": "1234567890",
"debtor_address": "Some existing address",
"creditor": null,
"creditor_name": "Creditor Company",
"creditor_country": "GB",
"creditor_regnum": "1234567890",
"creditor_address": "Some existing address",
"status": "pending",
"pay_method": "bank",
"net_amount": "10000.00",
"gross_amount": "12000.00",
"currency": "GBP",
"issue_date": "2018-04-25",
"due_date": "2018-05-21",
"paid_date": null,
"number": "AB2018-123",
"items": [
{
"description": "Super ergonomic chairs",
"quantity": "10.000",
"unit_price": "1000.00"
}
],
"source": null,
"policy": null,
"quote": null,
"estimated_quote_price": null,
"metadata": null,
"referral_url": "https://sandbox.hokodo.co/?transaction=trns-krF9xKJcjC28mKGV2byJof&key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"scheduled_payments": [],
"payments": []
},
]
}
List transactions created by your platform
View transaction
Requests
- without expanding referenced objects
GET /v1/transactions/<transaction_id> HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
curl --request GET \
--url https://api-sandbox.hokodo.co/v1/transactions/<transaction_id> \
--header "Authorization: <your_api_key>"
- with expanding referenced debtor, creditor, policy and quote objects
GET /v1/transactions/<transaction_id>?expand=debtor,creditor,policy,quote HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
curl --request GET \
--url https://api-sandbox.hokodo.co/v1/transactions/<transaction_id>?extend=debtor,creditor,policy,quote \
--header "Content-Type: application/json" \
--header "Authorization: <your_api_key>"
Responses
- regular response (with expanded debtor, creditor, policy and quote)
200 Ok
Content-Type: application/json
{
"url": "https://api-sandbox.hokodo.co/v1/transactions/trns-dTHo9Q2idffT7CMPCVjztA",
"id": "trns-dTHo9Q2idffT7CMPCVjztA",
"owner": "user-mECT3e5n9i7gVGrbn2Pd38",
"unique_id": "876987-987uinjojna-I8UH98Jnj",
"debtor": {
"url": "https://api-sandbox.hokodo.co/v1/companies/co-AgBGknk7D8KixY2ntbJtmT",
"id": "co-AgBGknk7D8KixY2ntbJtmT",
"country": "GB",
"name": "Some Existing Debtor",
"address": "2 Existing Street, London, SE11 6NQ",
"city": "London",
"postcode": "SE11 6NQ",
"legal_form": "Private limited with share capital",
"sectors": [
{
"system": "SIC2007",
"code": "96090"
}
],
"creation_date": "1910-10-10",
"identifiers": [
{
"idtype": "reg_number",
"country": "GB",
"value": "987654321"
}
],
"email": "",
"phone": "",
"status": "Active",
},
"debtor_name": "",
"debtor_country": "",
"debtor_regnum": "",
"debtor_address": "",
"creditor": {
"url": "https://api-sandbox.hokodo.co/v1/companies/co-K35WAmVFuSo6SCAPrSNdkP",
"id": "co-K35WAmVFuSo6SCAPrSNdkP",
"country": "GB",
"name": "Some Existing Creditor",
"address": "1 Existing Street, London, SW1E 5NN",
"city": "London",
"postcode": "SW1E 5NN",
"legal_form": "Public limited with share capital",
"sectors": [
{
"system": "SIC2007",
"code": "70100"
}
],
"creation_date": "1901-01-01",
"identifiers": [
{
"idtype": "reg_number",
"country": "GB",
"value": "012345678"
}
],
"email": "",
"phone": "",
"status": "Active",
},
"creditor_name": "",
"creditor_country": "",
"creditor_regnum": "",
"creditor_address": "",
"status": "pending",
"pay_method": "bank",
"net_amount": "10000.00",
"gross_amount": "12000.00",
"currency": "GBP",
"issue_date": "2020-04-25",
"due_date": "2020-07-21",
"paid_date": null,
"number": "AB2018-123",
"items": [
{
"description": "Super ergonomic chairs",
"quantity": "10.000",
"unit_price": "1000.00"
}
],
"source": null,
"policy": {
"url": "https://api-sandbox.hokodo.co/v1/policies/pol-V3h9nZQWDj9pxXWgkSjq8k",
"id": "pol-V3h9nZQWDj9pxXWgkSjq8k",
"number": "T-F9BE-13AF",
"status": "active",
"created": "2020-05-25T14:36:04.363353Z",
"documents": [],
"collection": null,
"loss_payee": "Not applicable"
},
"quote": {
"url": "https://api-sandbox.hokodo.co/v1/quotes/quo-YFaytjhqTD6ahBvjZdd5bV",
"id": "quo-YFaytjhqTD6ahBvjZdd5bV",
"client": {
"url": "https://api-sandbox.hokodo.co/v1/companies/co-K35WAmVFuSo6SCAPrSNdkP",
"id": "co-K35WAmVFuSo6SCAPrSNdkP",
"country": "GB",
"name": "John Lewis PLC",
"address": "171 Victoria Street, London, SW1E 5NN",
"city": "London",
"postcode": "SW1E 5NN",
"legal_form": "Public limited with share capital",
"sectors": [
{
"system": "SIC2007",
"code": "70100"
}
],
"creation_date": "1928-09-20",
"identifiers": [
{
"idtype": "reg_number",
"country": "GB",
"value": "00233462"
}
],
"email": "",
"phone": "",
"status": "Active",
},
"status": "accepted",
"proposed_quote": null,
"rejection_reason": null,
"created": "2020-05-25T14:17:50.385544Z",
"valid_until": "2020-05-25T16:17:50.344391Z",
"currency": "GBP",
"total_price": "97.75",
"premium": "87.28",
"ipt": "10.47",
"price": {
"currency": "GBP",
"total_price": "97.75",
"total_price_without_discount": "97.75",
"discount_amount": null,
"premium": "87.28",
"ipt": "10.47",
"discounts": []
},
"insured": {
"currency": "GBP",
"insured_amount": "9000.00"
},
"insured_pc_net": "90.0",
"insured_pc_gross": null,
"referral_url": null,
"payment_required": true
},
"estimated_quote_price": null,
"metadata": null,
"referral_url": null,
"scheduled_payments": [],
"payments": []
}
- transaction not found
404 Not Found
Content-Type: application/json
{
"detail": "Not found."
}
Look up a previously created transaction.
Errors
errors | description |
---|---|
404 | the transaction_id is probably invalid, the transaction has not been found |
Modify uninsured transaction
Request (e.g. identify debtor)
PATCH /v1/transactions/<transaction_id> HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"debtor": "co-AgBGknk7D8KixY2ntbJtmT"
}
curl --request PATCH \
--url https://api-sandbox.hokodo.co/v1/transactions/<transaction_id> \
--header "Content-Type: application/json" \
--header "Authorization: <your_api_key>" \
--data-binary "{
\"debtor\": \"co-4MRXDjtbScBmDzbrTbh9SW\"
}"
Response
200 Ok
Content-Type: application/json
{
"url": "https://api-sandbox.hokodo.co/v1/transactions/trns-krF9xKJcjC28mKGV2byJof",
"id": "trns-krF9xKJcjC28mKGV2byJof",
"owner": "user-mECT3e5n9i7gVGrbn2Pd38",
"unique_id": "876987-987uinjojna-I8UH98Jnj",
"debtor": "co-AgBGknk7D8KixY2ntbJtmT",
"debtor_name": "Debtor Company",
"debtor_country": "GB",
"debtor_regnum": "1234567890",
"debtor_address": "Some existing address",
"creditor": null,
"creditor_name": "Creditor Company",
"creditor_country": "GB",
"creditor_regnum": "1234567890",
"creditor_address": "Some existing address",
"status": "pending",
"pay_method": "bank",
"net_amount": "10000.00",
"gross_amount": "12000.00",
"currency": "GBP",
"issue_date": "2018-04-25",
"due_date": "2018-05-21",
"paid_date": null,
"number": "AB2018-123",
"items": [
{
"description": "Super ergonomic chairs",
"quantity": "10.000",
"unit_price": "1000.00"
}
],
"source": null,
"transaction_key": "tQ9OhMH-uxIvHswdISDce2sfVxpMRX3eEyx2RXs0YV4",
"estimated_quote_price": null,
"metadata": null,
"referral_url": null,
"scheduled_payments": [],
"payments": []
}
Partially modify a previously created and not yet insured transaction.
Once a transaction has been insured, only some specific fields can be modified, please use the dedicated endpoint to Modify an already insured transaction and amend the transaction post-sale.
Errors
errors | description |
---|---|
400 | a required field is missing or some of the fields have incorrect value |
409 | the transaction is already insured, modification is not allowed |
Delete transaction
Request
DELETE /v1/transactions/<transaction_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request DELETE \
--url https://api-sandbox.hokodo.co/v1/transactions/<transaction_id> \
--header "Authorization: <your_api_key>"
Responses
- regular response
204 No Content
- transaction not found
404 Not Found
Content-Type: application/json
{
"detail": "Not found."
}
- transaction already insured
409 Conflict
Content-Type: application/json
Delete a previously created transaction.
Errors
errors | description |
---|---|
404 | the transaction_id is probably invalid, the transaction has not been found |
409 | the transaction is already insured, deleting is not allowed |
Confirm a draft transaction
Request
PUT /v1/transactions/<transaction_id>/confirm HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
curl --request PATCH \
--url https://api-sandbox.hokodo.co/v1/transactions/<transaction_id>/paid \
--header "Content-Type: application/json" \
--header "Authorization: <your_api_key>"
Response
200 Ok
Content-Type: application/json
{
"url": "https://api-sandbox.hokodo.co/v1/transactions/trns-krF9xKJcjC28mKGV2byJof",
"id": "trns-krF9xKJcjC28mKGV2byJof",
"owner": "user-mECT3e5n9i7gVGrbn2Pd38",
"unique_id": "876987-987uinjojna-I8UH98Jnj",
"debtor": "co-AgBGknk7D8KixY2ntbJtmT",
"debtor_name": "Debtor Company",
"debtor_country": "GB",
"debtor_regnum": "1234567890",
"debtor_address": "Some existing address",
"creditor": null,
"creditor_name": "Creditor Company",
"creditor_country": "GB",
"creditor_regnum": "1234567890",
"creditor_address": "Some existing address",
"status": "paid",
"pay_method": "bank",
"net_amount": "10000.00",
"gross_amount": "12000.00",
"currency": "GBP",
"issue_date": "2018-04-25",
"due_date": "2018-05-21",
"paid_date": "2018-05-21",
"number": "AB2018-123",
"items": [
{
"description": "Super ergonomic chairs",
"quantity": "10.000",
"unit_price": "1000.00"
}
],
"source": null,
"policy": null,
"quote": null,
"estimated_quote_price": null,
"metadata": null,
"referral_url": null,
"scheduled_payments": [],
"payments": []
}
This endpoint lets you change the status of a draft transaction from draft to pending. For uninsured transactions, you may use the modify endpoint. This endpoint is particularly relevant for insured draft transactions: it is the only way to update their status.
Errors
errors | description |
---|---|
404 | the transaction_id is probably invalid, the transaction has not been found |
409 | the transaction is not in the draft status, modification from this endpoint is not allowed |
Mark a transaction as paid
Request
PUT /v1/transactions/<transaction_id>/paid HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"pay_method": "bank",
"paid_date": "2018-05-21"
}
curl --request PATCH \
--url https://api-sandbox.hokodo.co/v1/transactions/<transaction_id>/paid \
--header "Content-Type: application/json" \
--header "Authorization: <your_api_key>" \
--data-binary "{
\"pay_method\": \"bank\",
\"paid_date\": \"2018-05-21\"
}"
Response
200 Ok
Content-Type: application/json
{
"url": "https://api-sandbox.hokodo.co/v1/transactions/trns-krF9xKJcjC28mKGV2byJof",
"id": "trns-krF9xKJcjC28mKGV2byJof",
"owner": "user-mECT3e5n9i7gVGrbn2Pd38",
"unique_id": "876987-987uinjojna-I8UH98Jnj",
"debtor": "co-AgBGknk7D8KixY2ntbJtmT",
"debtor_name": "Debtor Company",
"debtor_country": "GB",
"debtor_regnum": "1234567890",
"debtor_address": "Some existing address",
"creditor": null,
"creditor_name": "Creditor Company",
"creditor_country": "GB",
"creditor_regnum": "1234567890",
"creditor_address": "Some existing address",
"status": "paid",
"pay_method": "bank",
"net_amount": "10000.00",
"gross_amount": "12000.00",
"currency": "GBP",
"issue_date": "2018-04-25",
"due_date": "2018-05-21",
"paid_date": "2018-05-21",
"number": "AB2018-123",
"items": [
{
"description": "Super ergonomic chairs",
"quantity": "10.000",
"unit_price": "1000.00"
}
],
"source": null,
"policy": null,
"quote": null,
"estimated_quote_price": null,
"metadata": null,
"referral_url": null,
"scheduled_payments": [],
"payments": []
}
If your platform is able to know when the invoice has been paid, you should call this endpoint to notify the API.
field | type | flags | description |
---|---|---|---|
pay_method | string | optional | Payment method |
paid_date | date | optional | Date when the transaction has been paid in full |
Errors
errors | description |
---|---|
404 | the transaction_id is probably invalid, the transaction has not been found |
Modify an already insured transaction
Request
PATCH /v1/transactions/<transaction_id>/amend/ HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"net_amount": "1000.00",
"gross_amount": "1200.00",
"issue_date": "2021-01-15",
"due_date": "2021-03-15",
"scheduled_payments": [
{"date": "2021-01-15", "amount": "1.00"},
{"date": "2021-03-15", "amount": "1199.00"},
]
}
curl --request PATCH \
--url https://api-sandbox.hokodo.co/v1/transactions/<transaction_id>/amend/ \
--header "Content-Type: application/json" \
--header "Authorization: <your_api_key>" \
--data-binary '{
"net_amount": "1000.00",
"gross_amount": "1200.00",
"issue_date": "2021-01-15",
"due_date": "2021-03-15",
"scheduled_payments": [
{"date": "2021-01-15", "amount": "1.00"},
{"date": "2021-03-15", "amount": "1199.00"},
]
}'
Response
200 Ok
Content-Type: application/json
{
"url": "https://api-sandbox.hokodo.co/v1/transactions/trns-krF9xKJcjC28mKGV2byJof",
"id": "trns-krF9xKJcjC28mKGV2byJof",
"owner": "user-mECT3e5n9i7gVGrbn2Pd38",
"unique_id": "876987-987uinjojna-I8UH98Jnj",
"debtor": "co-AgBGknk7D8KixY2ntbJtmT",
"debtor_name": "Debtor Company",
"debtor_country": "GB",
"debtor_regnum": "1234567890",
"debtor_address": "Some existing address",
"creditor": null,
"creditor_name": "Creditor Company",
"creditor_country": "GB",
"creditor_regnum": "1234567890",
"creditor_address": "Some existing address",
"status": "pending",
"pay_method": "unknown",
"net_amount": "1000.00",
"gross_amount": "1200.00",
"currency": "GBP",
"issue_date": "2021-01-15",
"due_date": "2021-03-15",
"paid_date": null,
"number": "AB2018-123",
"items": [],
"source": null,
"transaction_key": "tQ9OhMH-uxIvHswdISDce2sfVxpMRX3eEyx2RXs0YV4",
"estimated_quote_price": null,
"metadata": null,
"referral_url": null,
"scheduled_payments": [
{"date": "2021-01-15", "amount": "1.00"},
{"date": "2021-03-15", "amount": "1199.00"},
],
"payments": [
{"date": "2021-01-13", "amount": "1.00"},
]
}
Sometimes, an order on your platform gets modified after the sale. Maybe the customer has returned part of the order, or asked for a refund, or there was a mistake. Maybe the payment schedule has been altered for some reason.
The amendment endpoint allows a limited set of modifications after a transaction has been insured. It can cover the following cases:
- post-sale modification of the issue date and/or due date,
- post-sale partial refunds and/or modification of the payment schedule.
It is important to use this in order to maintain proper synchronisation of your database and Hokodo's database, and to minise manual operational load and data exchanges.
field | type | flags | description |
---|---|---|---|
net_amount | decimal | optional | Decimal value of the net transaction amount |
gross_amount | decimal | optional | Decimal value of the gross transaction amount |
issue_date | date | optional | Date of issuance of the transaction |
due_date | date | optional | Date due of the transaction |
scheduled_payments | list | optional | The list of partial payments, expected according to a defined schedule |
scheduled_payments[*][date] | string | required | Payment date |
scheduled_payments[*][amount] | decimal | required | Payment amount in transaction currency |
Notes
- If
scheduled_payments
is omitted, the existing schedule is not modified. Consistency checks are made:scheduled_payments
must matchgross_amount
if present.due_date
must match the date of the last scheduled payment.
- The permitted set of modifications (eg. increasing amount, modifying the issue date) will be determined by contractual agreement: please contact support@hokodo.co to arrange this.
Errors
errors | description |
---|---|
400 | a required field is missing or some of the fields have incorrect value |
409 | this modification is not allowed |
Transaction partial payments
Sample transaction with 3 installments over 60 days
"gross_amount": "300.00",
"issue_date": "2020-01-01",
"due_date": "2020-03-01",
"scheduled_payments": [
{
"date": "2020-01-01",
"amount": "100.00",
"currency": "EUR"
},
{
"date": "2020-02-01",
"amount": "100.00",
"currency": "EUR"
},
{
"date": "2020-03-01",
"amount": "100.00",
"currency": "EUR"
}
],
"payments": [
{
"date": "2020-01-01",
"amount": "100.00",
"currency": "EUR"
}
]
Sample transaction with 30 days payment terms and no initial payment
"gross_amount": "300.00",
"issue_date": "2020-01-01",
"due_date": "2020-03-01",
"scheduled_payments": [
{
"date": "2020-03-01",
"amount": "300.00",
"currency": "EUR"
}
],
"payments": []
A transaction may be paid back in multiple partial payments. If you are using
Hokodo insurance to cover transactions on your marketplace or e-commerce
platform, to provide payment terms to your buyers, please include the schedule
of expected payments with the Transaction
and notify us of the partial
payments as they arrive. In the event that a payment that you have recorded
is subsequently reported to fail or be reversed, please record this as
another payment but with a negative amount (see more information below).
You can find 2 examples of the relevant Transaction
fields in the code
samples in this sub-section:
If you want to check if you can insure a transaction in 3 installments over 60 days, including an initial payment at day 0.
If you want to check for 30 days payment terms with no initial payment.
You can then notify Hokodo of partial payments as they come through, as well as any chargebacks or negative events.
Transaction partial payments endpoints
GET /transactions/<transaction_id>/payments
POST /transactions/<transaction_id>/payments
Transaction partial payment object
{
"date": "2020-03-01",
"amount": "300.00",
"currency": "EUR",
"type": "settlement",
"details": "",
"provider_code": ""
}
field | type | flags | description |
---|---|---|---|
date | date | required | Date the scheduled payment is expected or the payment is received |
amount | decimal | required | Decimal value of the gross amount of the expected or received payment. Positive for settlements, negative for chargebacks |
currency | currency | optional | Currency of the payment amount |
type | string | depends | optional for positive amounts (and defaults to settlement ), required for negative amounts: chargeback , error , other , or unknown |
details | string | optional | free text field containing details about the reason, such as "The bank account has been closed" or "This payment could not be processed" |
provider_code | string | optional | rejection code from 3rd party payment provider, for example account_closed , insufficient_funds (Stripe), or 1 , B (GoCardless) |
Create transaction with partial payments
Requests
POST /v1/transactions HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"owner": "user-nNqgg5AFymQMumaU7EdrLa",
"debtor": "co-4MRXDjtbScBmDzbrTbh9SW",
"creditor": "co-7QCHuTN5AJycwX7iw9ofW2",
"net_amount": 10000,
"gross_amount": 12000,
"currency": "GBP",
"issue_date": "2020-01-01",
"due_date": "2020-03-01",
"number": "AB2020-123",
"items": [
{
"description": "Super ergonomic chairs",
"quantity": 10,
"unit_price": 1000
}
],
"unique_id": "876987-987uinjojna-I8UH98Jnj",
"scheduled_payments": [
{
"date": "2020-01-01",
"amount": "100.00",
"currency": "EUR"
},
{
"date": "2020-03-01",
"amount": "11900.00",
"currency": "EUR"
}
],
"payments": [
{
"date": "2020-01-01",
"amount": "100.00",
"currency": "EUR"
}
]
}
curl --request POST \
--url https://api-sandbox.hokodo.co/v1/transactions \
--header "Content-Type: application/json" \
--header "Authorization: <your_api_key>" \
--data-binary '{
"owner": "user-nNqgg5AFymQMumaU7EdrLa",
"debtor": "co-4MRXDjtbScBmDzbrTbh9SW",
"creditor": "co-7QCHuTN5AJycwX7iw9ofW2",
"net_amount": 10000,
"gross_amount": 12000,
"currency": "GBP",
"issue_date": "2020-01-01",
"due_date": "2020-03-01",
"number": "AB2020-123",
"items": [
{
"description": "Super ergonomic chairs",
"quantity": 10,
"unit_price": 1000
}
],
"unique_id": "876987-987uinjojna-I8UH98Jnj",
"scheduled_payments": [
{
"date": "2020-01-01",
"amount": "100.00",
"currency": "EUR"
},
{
"date": "2020-03-01",
"amount": "11900.00",
"currency": "EUR"
}
],
"payments": [
{
"date": "2020-01-01",
"amount": "100.00",
"currency": "EUR"
}
]
}'
Responses
201 Created
Content-Type: application/json
{
"url": "https://api-sandbox.hokodo.co/v1/transactions/trns-yQKxbtCg9aTS5JYnsRVA9B",
"id": "trns-yQKxbtCg9aTS5JYnsRVA9B",
"owner": "user-nNqgg5AFymQMumaU7EdrLa",
"unique_id": "876987-987uinjojna-I8UH98Jnj",
"debtor": "co-4MRXDjtbScBmDzbrTbh9SW",
"debtor_name": "",
"debtor_country": "",
"debtor_regnum": "",
"debtor_address": "",
"creditor": "co-7QCHuTN5AJycwX7iw9ofW2",
"creditor_name": "",
"creditor_country": "",
"creditor_regnum": "",
"creditor_address": "",
"status": "pending",
"pay_method": "",
"net_amount": "10000.00",
"gross_amount": "12000.00",
"currency": "GBP",
"issue_date": "2020-01-01",
"due_date": "2020-03-01",
"paid_date": null,
"number": "AB2020-123",
"items": [
{
"description": "Super ergonomic chairs",
"quantity": 10,
"unit_price": 1000
}
],
"source": null,
"transaction_key": "JqzI0T5W7FFdUODv9vkU2bXOTJyV2kT7-Ku2ESJJKXQ",
"estimated_quote_price": null,
"metadata": null,
"referral_url": "https://sandbox.hokodo.co/?transaction=trns-yQKxbtCg9aTS5JYnsRVA9B&key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"scheduled_payments": [
{
"date": "2020-01-01",
"amount": "100.00",
"currency": "EUR"
},
{
"date": "2020-03-01",
"amount": "11900.00",
"currency": "EUR"
}
],
"payments": [
{
"date": "2020-01-01",
"amount": "100.00",
"currency": "EUR"
}
]
}
- error response (example)
400 Bad Request
Content-Type: application/json
{
"due_date": [
"If you provide a payment schedule, this field is required."
]
}
- error response (example)
400 Bad Request
Content-Type: application/json
{
"scheduled_payments": [
"Scheduled amounts and gross amount are not equal."
]
}
Some things to keep in mind when creating a Transaction
with scheduled payments
(and optionally initial payments):
If there are no initial payments, such as an upfront amount,
payments
can be left empty as[]
.The
amount
in all scheduled payments and payments are meant as gross amounts, tax included. We currently don't support partial payments on platforms where the net amount, excluding tax, is insured. If that is your case, please let us know.The sum of scheduled payments should be equal to the invoice
gross_amount
.PUT
/PATCH
andDELETE
methods are not allowed, payments should not be modified. If, for example, a chargeback happens on a payment, please add a new negative payment with the amount and details of the chargeback.The invoice
due_date
should match the date of the last scheduled payment.In a received payment (
payments
, notscheduled_payments
),date
is optional, and defaults to today's date if absent.Once the sum of all received payments (
payments
) reaches the invoice's gross_amount, the transaction is automatically marked as paid, and you do NOT need to do it using the dedicated endpoint. If the sum exceeds thegross_amount
, you won't receive an error, but we may manually verify the transaction.
Errors
errors | description |
---|---|
400 | a required field is missing or some of the fields have incorrect value |
Create a new payment for an existing transaction
Request
- positive amount (settlement)
POST /v1/transactions/trns-yQKxbtCg9aTS5JYnsRVA9B/payments/ HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"date": "2021-02-01",
"amount": "100.00",
"currency": "EUR"
}
curl --request POST \
--url https://api-sandbox.hokodo.co/v1/transactions/trns-yQKxbtCg9aTS5JYnsRVA9B/payments/ \
--header "Content-Type: application/json" \
--header "Authorization: <your_api_key>"
--data-binary '{
{
"date": "2020-02-01",
"amount": "100.00",
"currency": "EUR"
}
}'
- negative amount (failure, chargeback, etc.)
POST /v1/transactions/trns-yQKxbtCg9aTS5JYnsRVA9B/payments/ HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"date": "2021-02-01",
"amount": "-100.00",
"currency": "EUR",
"type": "error",
"details": "The bank account has been closed.",
"provider_code": "account_closed"
}
curl --request POST \
--url https://api-sandbox.hokodo.co/v1/transactions/trns-yQKxbtCg9aTS5JYnsRVA9B/payments/ \
--header "Content-Type: application/json" \
--header "Authorization: <your_api_key>"
--data-binary '{
{
"date": "2021-02-01",
"amount": "-100.00",
"currency": "EUR",
"type": "error",
"details": "The bank account has been closed.",
"provider_code": "account_closed"
}'
Response
- positive amount (settlement)
201 OK
Content-Type: application/json
{
"id": "pmnt-z3j4Se4yEnRaYyvDR8ZXcN",
"date": "2021-02-01",
"amount": 100.00,
"currency": "EUR"
"type": "settlement",
"details": "",
"provider_code": ""
}
- negative amount (failure, chargeback, etc.)
201 OK
Content-Type: application/json
{
"id": "pmnt-z3j4Se4yEnRaYyvDR8ZXcN",
"date": "2021-02-01",
"amount": "-100.00",
"currency": "EUR",
"type": "error",
"details": "The bank account has been closed.",
"provider_code": "account_closed"
}
Notify Hokodo of a partial payment linked to a transaction.
field | type | flags | description |
---|---|---|---|
date | date | required | Date the scheduled payment is expected or the payment is received |
amount | decimal | required | Decimal value of the gross amount of the expected or received payment. Positive for settlements, negative for chargebacks |
currency | currency | optional | Currency of the payment amount |
type | string | depends | optional for positive amounts (and defaults to settlement ), required for negative amounts: chargeback , error , other , or unknown |
details | string | optional | free text field containing details about the reason, such as "The bank account has been closed" or "This payment could not be processed" |
provider_code | string | optional | rejection code from 3rd party payment provider, for example account_closed , insufficient_funds (Stripe), or 1 , B (GoCardless) |
If the payment amount
is positive, it means the payment is a settlement (the customer / end-user
has settled part of the transaction).
If the payment amount
is negative, it means money flowed the other way
or you have learned a settlement has failed, in which case we ask you to negate that settlement..
Many payment providers only notify of payment errors (eg. "insufficient funds")
a few days after having already reported the settlement as having been successful. Or,
the customer can dispute the payment and execute a chargeback at any time for weeks
following the settlement. In these cases, the type
field must be present with one of the values
(chargeback
, refund
, error
, unknown
), and additional details are expected
in the free text fields details
and provider_code
:
chargeback
: a dispute from the customer resulted in the customer executing a chargeback/reversal of the settlementrefund
: a sum has been paid back to the customer as a result of product return or order modificationerror
: an error has occurred (for example lack of funds in the account, wrong account number or a technical error) that is not related to an active dispute by the customer. There is typically a reporting lag with payment providers, and as such you only get notified of these errors a few days following being told of a successful settlement.unknown
: the settlement has failed, perhaps due to an active chargeback or error, but you are unable to specify the reason at the time of notifying Hokodo.
It is expected that if you notify us of a negative payment, a positive payment of the same or greater amount has already happened before.
The fields details
and provider_code
should be filled with details of the
error or chargeback, that you will usually get from the payment provider. You will
find some examples below from Stripe and GoCardless.
chargeback
Reversal of payment in case of dispute
type | provider_code | details |
---|---|---|
chargeback | debit_not_authorized | The customer has notified their bank that this payment was unauthorized or there is no mandate held by the paying bank |
chargeback | 4 | Your customer has disputed having been notified of this Direct Debit. |
chargeback | 7 | Your customer has disputed that the amount taken differs from the amount they were notified of. |
chargeback | Purchases that have been made without the buyer’s knowledge or consent | |
chargeback | Purchases that were paid for but haven’t been received | |
chargeback | Purchases that the buyer has been billed for more than once, purchases that have been billed incorrectly, or refunds that haven’t been issued |
error
Reversal of payment because of payment failure or various errors
type | provider_code | details |
---|---|---|
error | account_closed | The bank account has been closed. |
error | bank_ownership_changed | The account has been transferred to a new Payment Service Provider (PSP). Check if you have been notified of the new PSP’s details. If not, you must collect a new mandate from the customer. |
error | invalid_account_number | The account number is not valid. This could mean it is not for a GBP account or that the account cannot process Direct Debit payments. |
error | insufficient_funds | The customer’s account has insufficient funds to cover this payment. |
error | generic_could_not_process | This payment could not be processed. |
error | 0 | The payer's bank wasn't in a position to pay the Direct Debit. Generally this is due to insufficient funds. You should contact your customer and arrange to re-try taking the payment. |
error | 3 | Your customer's DDI has been transferred to a new bank account, and you submitted payment to the old account. |
error | B | Your customer's DDI has been cancelled as they've closed their bank account. |
error | 5 | The paying bank didn't recognise the account number you submitted. It's likely that no DDI is set up. |
error | 2 | Your customer's DDI will also have been cancelled. |
error | 6 | Your customer doesn't have a DDI set up with you. In rare cases, this may be due to a small bank requiring additional time to set up a Direct Debit. |
error | 1 | You tried to collect payment against a cancelled DDI. |
error | 8 | Usually caused by submission of a payment before a DDI is fully set up (less than 2 working days after submission). This may also be raised if you attempt to take a payment before the date your customer was notified of. |
error | 9 | You attempted to collect a payment more than 3 working days after the date you notified your customer of. |
error | A | Your details don't match the details on the customer's DDI. |
unknown
For an error/dispute, in case you don't have access to the details. It is still important for us to be informed of the negative payment event even if you can't provide the extra information.
type | provider_code | details |
---|---|---|
unknown |
refund
Return of cash as a result of product return or order modification.
For a refund event you might have no information to fill in the details
or provider_code
fields,
but we would welcome any additional data that you provide.
type | provider_code | details |
---|---|---|
refund | Order amount decreased and extra payment returned to the customer |
List transaction payments
Request
POST /v1/transactions/trns-yQKxbtCg9aTS5JYnsRVA9B/payments/ HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
curl --request GET \
--url https://api-sandbox.hokodo.co/v1/transactions/trns-yQKxbtCg9aTS5JYnsRVA9B/payments/ \
--header "Content-Type: application/json" \
--header "Authorization: <your_api_key>"
Response
200 OK
Content-Type: application/json
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "pmnt-z3j4Se4yEnRaYyvDR8ZXcN",
"date": "2020-01-01",
"amount": "100.00",
"currency": "EUR"
}
]
}
List partial payments linked to a transaction
Quotes
These resources allow you to request a quote, an offer for an insurance policy. They require having a transaction
created, owned by a user
or an organisation
from your platform.
If the client
company, or any of the creditor
and the debtor
of the transaction are not identified, the API will try to find a close match to propose a quote. The quote might be incorrect if companies are not correctly identified.
In most cases, the client
company will be the same as the creditor
company and as such it can be omitted
from the request.
A transaction can only have one valid quote at a time: any new quote request makes previous ones expired. A quote can be accepted and paid for to obtain a proper policy. Editing the transaction makes any outstanding quote offer expired. A new quote must be requested.
Note that after a quote has been offered, the client is not insured yet. The quote must be accepted, and the price of the insurance paid before the insurance takes effect.
Quotes endpoints
POST /v1/quotes
GET /v1/quotes
GET /v1/quotes/<quote_id>
DELETE /v1/quotes/<quote_id>
Quote object
{
"url": "https://api-sandbox.hokodo.co/v1/quotes/quo-EzH6BixNSHvaByEpXcFW5h",
"id": "quo-EzH6BixNSHvaByEpXcFW5h",
"transaction": "trns-dTHo9Q2idffT7CMPCVjztA",
"client": "co-K35WAmVFuSo6SCAPrSNdkP",
"status": "offered",
"payment_required": true,
"created": "2020-05-25T11:37:56.821701Z",
"valid_until": "2020-05-25T13:37:56.764518Z",
"policy": null,
"referral_url": "https://sandbox.hokodo.co/#/?quote=quo-EzH6BixNSHvaByEpXcFW5h&transaction=trns-dTHo9Q2idffT7CMPCVjztA&key=xnwLGPAMu0q5R2mIG80s7q-OQsVk5YBNr60ifNSoyLQ",
"insured": {
"currency": "GBP",
"insured_amount": "9000.00"
},
"insured_pc_net": 90,
"insured_pc_gross": null
"rejection_reason": null,
"currency": "GBP",
"total_price": "97.75",
"ipt": "10.47",
"premium": "87.28",
"price": {
"currency": "GBP",
"total_price": "97.75",
"ipt": "10.47",
"premium": "87.28",
"total_price_without_discount": "97.75",
"discount_amount": null,
"discounts": []
},
"proposed_quote": null,
}
field | type | description |
---|---|---|
url | string | API endpoint to access the quote |
id | string(uuid) | API identifier of the quote |
transaction | string(uuid) | API identifier of the transaction |
client | string(uuid) | API identifier of the company requesting an insurance quote |
status | string | Status of the quote, see Quote status |
payment_required | boolean | True if payment is required for the quote to be accepted (can be False if eg. discount makes the quote free) |
created | datetime | Date of quote request |
valid_until | datetime | Validity limit if offered |
policy | string | API identifier of the policy if the quote is accepted (always null at creation) |
referral_url | string | A URL for referring the customer to Hokodo Quote&Buy website, see Referral URL |
insured | dictionary | Components of the insured amount |
insured[currency] | currency | Currency of the insured amount |
insured[insured_amount] | decimal | Net amount that will be insured if quote is accepted |
insured_pc_net | decimal | Percentage of net invoice value covered by policy when relevant |
insured_pc_gross | decimal | Percentage of gross invoice value covered by policy when relevant |
rejection_reason | dictionary | Rejection reason if quote is declined, see Rejection reasons |
rejection_reason[code] | string | A text label identifying the reason |
rejection_reason[detail] | string | A sentence in client language that can be shown to a user |
rejection_reason[params] | dictionary | A dictionary of dynamic key-value pairs used to build the "detail" string |
currency | string | Currency for all price amounts |
total_price | decimal | Price that would be charged to the customer (including taxes) |
ipt | decimal | Insurance tax |
premium | decimal | Premium part of the amount charged to the customer (net of IPT, before deducting payment fees) |
price | dictionary | Components of the policy price with currency |
price[currency] | currency | Currency for all price amounts |
price[total_price] | decimal | Price that would be charged to the customer (including taxes) |
price[ipt] | decimal | Insurance tax |
price[premium] | decimal | Premium part of the amount charged to the customer (net of IPT, before deducting payment fees) |
price[total_price_without_discount] | decimal | Price that would be charged to the customer before discounts |
price[discount_amount] | decimal | Total amount of discounts applicable to the quote |
price[discounts] | list | List of discounts applicable to the quote |
price[discounts][*][type] | string | Type of the discount (currently only "credits") |
price[discounts][*][reason] | string | Reason for applying the discount, ready to be shown to the user |
price[discounts][*][discount_amount] | decimal | Amount of the discount |
price[discounts][*][remaining_credits_amount_after] | decimal | Amount of remaining credits once a policy for this quote is bought |
price[discounts][*][remaining_credits_amount_after_currency] | currency | Currency of remaining amount |
proposed_quote | null | Deprecated: this feature has been removed, the field has been kept for backwards compatibility |
Some price fields are duplicated in the "root" level and in the price
dictionary.
Quote status
Note that after an offer has been made, the client is not insured yet. The offer must be accepted, and the price of the insurance paid before the insurance takes effect.
The quote status is one of:
declined
: no offer has been madeoffered
: a valid offer is availableexpired
: a previous offer has been made but is no longer availableaccepted
: the transaction is insured, the quote having been accepted
Rejection reason
The rejection code
, params
and detail
can be one of the following:
code | params (keys) | detail |
---|---|---|
seller-country | creditor_country | We're not currently able to insure Sellers domiciled in {creditor_country}. |
seller-profile | At this stage we are not able to insure sellers fitting your profile. | |
seller-status | creditor_status | The status of the Seller on this invoice is registered as being {creditor_status} and so we cannot offer insurance. |
seller-accounts | creditor_accounts_type | We are not currently able to insure Sellers where the Seller's accounts have the status {creditor_accounts_type}. |
seller-country-subdivision | public_subdivision | We are not currently able to insure Sellers in this location: {public_subdivision}. |
seller-too-young | MIN_CREATION_YEARS | We're not able to insure Sellers who incorporated fewer than {MIN_CREATION_YEARS} years ago. |
seller-accounts-overdue | MAX_ACCOUNTS_OVERDUE_MONTHS | We're not currently able to insure Sellers when their accounts are overdue by more than {MAX_ACCOUNTS_OVERDUE_MONTHS} months. |
seller-accounts-too-old | MAX_AGE_LATEST_FINANCIALS | We're not currently able to insure you because your accounts are too old: they were published more than {MAX_AGE_LATEST_FINANCIALS} days ago. |
seller-invoices-overdue | We're unable to provide a quote because you have too many overdue invoices. | |
seller-too-young-on-platform | platform_name, customer_min_registration_days | Invoice Protection is only available for users who have been registered on {platform_name} for at least {customer_min_registration_days} days. |
seller-sector | We're not presently able to offer insurance to companies in the sector you are registered as operating in. | |
seller-company-type | legal_form | We don't presently offer insurance to companies that are incorporated as {legal_form}. |
seller-limit | This invoice would exceed the limit of the value of invoices that Hokodo can insure for your company as a Seller. | |
buyer-too-young | MIN_CREATION_YEARS | We're not presently able to insure Buyer companies which incorporated fewer than {MIN_CREATION_YEARS} years ago. |
buyer-country | debtor_country | We're not currently able to insure Buyers domiciled in {debtor_country}. |
buyer-profile | At this stage, we are not able to insure buyers fitting this profile. | |
buyer-status | debtor_status | The status of the Buyer on this invoice is registered as being "{debtor_status}" and so we cannot offer insurance. |
buyer-company-type | legal_form | We don't presently insure invoices to companies that are incorporated as {legal_form}. |
buyer-overdue-with-seller | OVERDUE_DAYS | The Buyer on this invoice has a {OVERDUE_DAYS}+ days overdue invoice with the Seller, so we're not able to insure at present. |
buyer-accounts | accounts_type | We are not currently able to insure Buyers where the Buyer's accounts have the status {accounts_type}. |
buyer-accounts-overdue | MAX_ACCOUNTS_OVERDUE_MONTHS | We're not currently able to insure Buyers when their accounts are overdue by more than {MAX_ACCOUNTS_OVERDUE_MONTHS} months. |
buyer-accounts-too-old | MAX_AGE_LATEST_FINANCIALS | We're not currently able to insure against Buyers whose accounts are too old: this Buyers accounts were published more than {MAX_AGE_LATEST_FINANCIALS} days ago. |
buyer-country-subdivision | public_subdivision | We are not currently able to insure Buyers in this location: {public_subdivision}. |
buyer-size | company_size | Hokodo is not presently able to insure companies of the size: {company_size}. |
buyer-pre-approved | platform_name | This buyer has not been pre-approved for Hokodo's insurance via {platform_name} |
buyer-limit | This invoice would exceed the limit of the value of invoices that Hokodo can insure for this company as a Buyer. | |
buyer-no-financials | The buyer on this invoice hasn't published any financials yet or doesn't have any assets. | |
buyer-uncreditworthy | We are unable to verify the creditworthiness of the buyer on this invoice. | |
buyer-high-risk | We are unable to insure this buyer due their high risk profile. | |
buyer-high-risk-long-term | max_term | We are unable to insure for this duration due to the buyer's high risk profile. We can insure durations up to {max_term}. |
buyer-sector | We don't cover invoices against buyer operating in this sector. | |
buyer-risk-appetite | tx_currency, debtor_risk_appetite | It's only possible for us to cover invoices up to a value of {tx_currency} {debtor_risk_appetite} at the moment, and your request for cover would cause us to exceed that limit. |
common-parent | The Buyer and Seller companies on this invoice appear to be related and so we cannot offer insurance. | |
connected-companies | The Buyer and Seller companies on this invoice appear to be related and so we cannot offer insurance. | |
invoice-currency | tx_currency | We don't currently insure invoices in the currency {tx_currency}. |
invoice-too-early | future_dated_limit_days | At the moment, we can only insure invoices issued up to {future_dated_limit_days} days into the future. |
invoice-too-late | today, tx_due_date | Today ({today}) is too close to, or past, the due date of the invoice ({tx_due_date}) for us to insure. |
invoice-too-large | website_email | Due to the size of this invoice, please contact {website_email} and we may be able to cover it manually. |
invoice-profile | We are not able to insure any further invoices of this profile at this time. | |
invoice-remaining-terms | credit_terms_days | This invoice's remaining credit terms are {credit_terms_days} days, which is longer than the maximum we're presently able to insure. |
invoice-credit-terms | credit_terms_days, MAX_CREDIT_TERMS_DAYS | This invoice's credit terms are {credit_terms_days} days. At the moment, we can only insure a maximum credit term of {MAX_CREDIT_TERMS_DAYS} days. |
sector-accum-limit | We are not able to insure any further invoices in the sector that either the buyer or seller is registered as operating in. |
Referral URL
The referral URL includes a secret key that allows limited access to transaction upon which the quote is based. The link allows a customer with just the link (no login/password required) to confirm the details of the transaction and purchase insurance.
Request a new quote
Request
POST /v1/quotes HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"transaction": "trns-dTHo9Q2idffT7CMPCVjztA"
}
curl --request POST \
--url https://api-sandbox.hokodo.co/v1/quotes \
--header "Content-Type: application/json" \
--header "Authorization: <your_api_key>" \
--data-binary "{
\"transaction\": \"trns-dTHo9Q2idffT7CMPCVjztA\"
}"
Responses
- quote offered
201 Created
Content-Type: application/json
{
"url": "https://api-sandbox.hokodo.co/v1/quotes/quo-EzH6BixNSHvaByEpXcFW5h",
"id": "quo-EzH6BixNSHvaByEpXcFW5h",
"transaction": "trns-dTHo9Q2idffT7CMPCVjztA",
"client": "co-K35WAmVFuSo6SCAPrSNdkP",
"status": "offered",
"proposed_quote": null,
"rejection_reason": null,
"created": "2020-05-25T11:37:56.821701Z",
"valid_until": "2020-05-25T13:37:56.764518Z",
"currency": "GBP",
"total_price": "97.75",
"premium": "87.28",
"ipt": "10.47",
"price": {
"currency": "GBP",
"total_price": "97.75",
"total_price_without_discount": "97.75",
"discount_amount": null,
"premium": "87.28",
"ipt": "10.47",
"discounts": []
},
"insured": {
"currency": "GBP",
"insured_amount": "9000.00"
},
"insured_pc_net": 90,
"insured_pc_gross": null,
"policy": null,
"referral_url": "https://sandbox.hokodo.co/#/?quote=quo-EzH6BixNSHvaByEpXcFW5h&transaction=trns-dTHo9Q2idffT7CMPCVjztA&key=xnwLGPAMu0q5R2mIG80s7q-OQsVk5YBNr60ifNSoyLQ",
"payment_required": true
}
- quote rejected
201 Created
Content-Type: application/json
{
"url": "https://api-sandbox.hokodo.co/v1/quotes/quo-3VezfMFGKX6U247jRhXAkQ",
"id": "quo-3VezfMFGKX6U247jRhXAkQ",
"transaction": "trns-yQKxbtCg9aTS5JYnsRVA9B",
"client": "co-K35WAmVFuSo6SCAPrSNdkP",
"status": "declined",
"proposed_quote": null,
"rejection_reason": {
"code": "invoice-too-late",
"detail": "Today (2020-05-25) is too close to, or past, the due date of the invoice (2018-05-21) for us to insure.",
"params": {
"today": "2020-05-25",
"tx_due_date": "2018-05-21"
}
},
"created": "2020-05-25T10:12:35.239884Z",
"valid_until": "2025-05-24T10:12:35.212006Z",
"currency": "",
"total_price": null,
"premium": null,
"ipt": null,
"price": null,
"insured": {
"currency": "GBP",
"insured_amount": "9000.00"
},
"insured_pc_net": 90,
"insured_pc_gross": null,
"policy": null,
"referral_url": null,
"payment_required": false
}
This endpoint is used to obtain a quote to insure a transaction. The only required field is transaction
. client
is optional and will default to the transaction's debtor
company. If you want the client to be different, the preferred way is to provide the client's API unique identifier in the client
field. However, you may use client_country
in conjunction with client_name
and / or client_regnum
.
If the quote's client
, the transaction's debtor
or the transaction's creditor
are null
, they will internally be matched to companies. The user must be offered the opportunity to review the result of this matching before accepting and paying for the insurance.
field | type | flags | description |
---|---|---|---|
transaction | string(uuid) | required | API unique identifier of the transaction |
client | string(uuid) | preferred | API unique identifier of the insured company |
client_name | string | optional | Name of the insured company |
client_country | country | optional | Country of the insured company |
client_regnum | string | optional | Registration number of the insured company |
client_address | string | optional | Address of the insured company |
Errors
errors | description |
---|---|
400 | a required field is missing |
409 | can't obtain a quote as transaction is already insured |
List quotes
Request
GET /v1/quotes HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET \
--url https://api-sandbox.hokodo.co/v1/quotes \
--header "Authorization: <your_api_key>"
}"
Response
200 Ok
Content-Type: application/json
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"url": "https://api-sandbox.hokodo.co/v1/quotes/quo-EzH6BixNSHvaByEpXcFW5h",
"id": "quo-EzH6BixNSHvaByEpXcFW5h",
"transaction": "trns-dTHo9Q2idffT7CMPCVjztA",
"client": "co-K35WAmVFuSo6SCAPrSNdkP",
"status": "offered",
"proposed_quote": null,
"rejection_reason": null,
"created": "2020-05-25T11:37:56.821701Z",
"valid_until": "2020-05-25T13:37:56.764518Z",
"currency": "GBP",
"total_price": "97.75",
"premium": "87.28",
"ipt": "10.47",
"price": {
"currency": "GBP",
"total_price": "97.75",
"total_price_without_discount": "97.75",
"discount_amount": null,
"premium": "87.28",
"ipt": "10.47",
"discounts": []
},
"insured": {
"currency": "GBP",
"insured_amount": "9000.00"
},
"insured_pc_net": "90.0",
"insured_pc_gross": null,
"policy": null,
"referral_url": "https://sandbox.hokodo.co/#/?quote=quo-EzH6BixNSHvaByEpXcFW5h&transaction=trns-dTHo9Q2idffT7CMPCVjztA&key=xnwLGPAMu0q5R2mIG80s7q-OQsVk5YBNr60ifNSoyLQ",
"payment_required": true
},
{
"url": "https://api-sandbox.hokodo.co/v1/quotes/quo-3VezfMFGKX6U247jRhXAkQ",
"id": "quo-3VezfMFGKX6U247jRhXAkQ",
"transaction": "trns-yQKxbtCg9aTS5JYnsRVA9B",
"client": "co-K35WAmVFuSo6SCAPrSNdkP",
"status": "declined",
"proposed_quote": null,
"rejection_reason": {
"code": "invoice-too-late",
"detail": "Today (2020-05-25) is too close to, or past, the due date of the invoice (2018-05-21) for us to insure.",
"params": {
"today": "2020-05-25",
"tx_due_date": "2018-05-21"
}
},
"created": "2020-05-25T10:12:35.239884Z",
"valid_until": "2025-05-24T10:12:35.212006Z",
"currency": "",
"total_price": null,
"premium": null,
"ipt": null,
"price": null,
"insured": {
"currency": "GBP",
"insured_amount": "9000.00"
},
"insured_pc_net": 90,
"insured_pc_gross": null,
"policy": null,
"referral_url": null,
"payment_required": false
}
]
}
List all previously requested quotes
View quote
Request
GET /v1/quotes/<quote_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET \
--url https://api-sandbox.hokodo.co/v1/quotes/<quote_id> \
--header "Authorization: <your_api_key>"
}"
Responses
- regular response
200 Ok
Content-Type: application/json
{
"url": "https://api-sandbox.hokodo.co/v1/quotes/quo-EzH6BixNSHvaByEpXcFW5h",
"id": "quo-EzH6BixNSHvaByEpXcFW5h",
"transaction": "trns-dTHo9Q2idffT7CMPCVjztA",
"client": "co-K35WAmVFuSo6SCAPrSNdkP",
"status": "offered",
"proposed_quote": null,
"rejection_reason": null,
"created": "2020-05-25T11:37:56.821701Z",
"valid_until": "2020-05-25T13:37:56.764518Z",
"currency": "GBP",
"total_price": "97.75",
"premium": "87.28",
"ipt": "10.47",
"price": {
"currency": "GBP",
"total_price": "97.75",
"total_price_without_discount": "97.75",
"discount_amount": null,
"premium": "87.28",
"ipt": "10.47",
"discounts": []
},
"insured": {
"currency": "GBP",
"insured_amount": "9000.00"
},
"insured_pc_net": "90.0",
"insured_pc_gross": null,
"policy": null,
"referral_url": "https://sandbox.hokodo.co/#/?quote=quo-EzH6BixNSHvaByEpXcFW5h&transaction=trns-dTHo9Q2idffT7CMPCVjztA&key=xnwLGPAMu0q5R2mIG80s7q-OQsVk5YBNr60ifNSoyLQ",
"payment_required": true
}
- not found
http-doc 404 Not Found Content-Type: application/json
json-doc { "detail": "Not found." }
Retrieve a previously requested quote
Errors
errors | description |
---|---|
404 | the quote id is probably incorrect, a quote has not been found |
Delete quote
Request
DELETE /v1/quotes/<quote_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request DELETE \
--url https://api-sandbox.hokodo.co/v1/quotes/<quote_id> \
--header "Authorization: <your_api_key>"
}"
Responses
- regular response
204 No Content
- not found
404 Not Found
Content-Type: application/json
{
"detail": "Not found."
}
- unable to delete accepted quote
409 Conflict
Content-Type: application/json
Delete a previously requested quote
Errors
errors | description |
---|---|
404 | the quote id is probably incorrect, a quote has not been found |
409 | can't delete the quote, probably because it's already been accepted |
Policies
To accept a quote and initiate actual insurance, create a Policy.
If you refer your customers to our quote and payment page, we will take care of this part. Otherwise, you can use our API to do it.
Note: A policy cannot be deleted or modified through API.
Policies endpoints
POST /v1/policies
GET /v1/policies
GET /v1/policies/<policy_id>
Policy object
{
"url": "https://api-sandbox.hokodo.co/v1/policies/pol-V3h9nZQWDj9pxXWgkSjq8k",
"id": "pol-V3h9nZQWDj9pxXWgkSjq8k",
"number": "T-F9BE-13AF",
"quote": "quo-YFaytjhqTD6ahBvjZdd5bV",
"status": "active",
"created": "2020-05-25T14:36:04.363353Z",
"documents": [],
"collection": null,
"loss_payee": "Not applicable"
}
field | type | description |
---|---|---|
url | string | API endpoint to access the policy |
id | string(uuid) | API identifier of the policy |
number | string | Public identifier of the policy |
quote | string(uuid) | API identifier of the related quote |
status | string | Status of the policy, see below |
created | datetime | Date of creation of the policy |
documents | list | List of documents attached to the policy, see below |
documents[*][category] | string | Category of the document |
documents[*][url] | string | URL to download the document |
collection | string | Identifier of a collection resource (available after collection is initiated) |
loss_payee | string | Name of the company that will be loss payee (not always applicable) |
Policy status
The policy status is one of:
active
late
late_can_handover
paid_distributor
paid
elapsed
under_collection
pay_installments
not_collectable
not_collectable_dispute
under_collection_installments
dispute_pursual
under_collection_dispute_solved
claim_submitted
claim_approved
claim_rejected
recovery_installments
recovery_underway
recovery_complete
recovery_rejected
cancelled
other
If your platform is able to know when the invoice has been paid, you should call endpoint
/transactions/<transaction_id>/paid
to notify the API.
Policy documents
After a policy insurance has been accepted, the client can retrieve the policy documents, using links
provided in the documents
section of the policy object
Documents are available in PDF format and may contain:
- general conditions
- details about the invoice insured
Create policy
Request
POST /v1/policies HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"quote": "quo-EzH6BixNSHvaByEpXcFW5h",
"stripe_id: "tok_1DRHM2KvLUV9XNYvo4vNGeDi"
}
curl --request POST \
--url https://api-sandbox.hokodo.co/v1/quotes \
--header "Content-Type: application/json" \
--header "Authorization: <your_api_key>" \
--data-binary "{
\"quote\": \"trns-dTHo9Q2idffT7CMPCVjztA\",
\"stripe_id\": \"tok_1DRHM2KvLUV9XNYvo4vNGeDi\"
}"
Responses
- regular response
201 Created
Content-Type: application/json
{
"url": "https://api-sandbox.hokodo.co/v1/policies/pol-V3h9nZQWDj9pxXWgkSjq8k",
"id": "pol-V3h9nZQWDj9pxXWgkSjq8k",
"number": "T-F9BE-13AF",
"quote": "quo-YFaytjhqTD6ahBvjZdd5bV",
"status": "active",
"created": "2020-05-25T14:36:04.363353Z",
"documents": [],
"collection": null,
"loss_payee": "Not applicable"
}
- error response (payment information not provided)
400 Bad Request
Content-Type: application/json
{
"non_field_errors": [
"Invalid payment information."
]
}
- error response (invalid StripeID type)
400 Bad Request
Content-Type: application/json
{
"detail": "Attempted to purchase a policy with an invalid stripe_id type: invalid.stripe_id must be a valid PaymentMethod, Source or Token."
}
- error response (quote expired)
400 Bad Request
Content-Type: application/json
{
"quote": [
"Quote is expired."
]
}
- error response (quote already accepted)
400 Bad Request
Content-Type: application/json
{
"quote": [
"Quote is already accepted."
]
}
- payment failed
402 Payment Required
Content-Type: application/json
{
"detail": "Payment failed."
}
This endpoint is used to obtain a policy from a quote. The quote needs to be accepted, and valid payment details should be provided for the total amount requested. The quote must have been offered and still be valid at the time of the call.
Payment is made using Stripe API. A valid Stripe Token or Source should be used so that it can be charged by backend. Please refer to Stripe API documentation for how to obtain a Source or a Token identifier. Never send raw bank or payment information through this endpoint (no bank account, no card number).
Once a policy has been created without error, the insurance takes effect, providing that all information collected is correct.
field | type | flags | description |
---|---|---|---|
quote | string(uuid) | required | API unique identifier of the quote |
stripe_id | string | required | Valid Stripe Token or Source |
Errors
errors | description |
---|---|
400 | required field is missing or quote has expired or was accepted |
402 | payment failed |
502 | payment processor responded with a system error |
504 | timeout happened when accessing payment provider |
List policies
Request
GET /v1/policies HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET \
--url https://api-sandbox.hokodo.co/v1/policies \
--header "Authorization: <your_api_key>"
}"
Response
200 Ok
Content-Type: application/json
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"url": "https://api-sandbox.hokodo.co/v1/policies/pol-V3h9nZQWDj9pxXWgkSjq8k",
"id": "pol-V3h9nZQWDj9pxXWgkSjq8k",
"number": "T-F9BE-13AF",
"quote": "quo-YFaytjhqTD6ahBvjZdd5bV",
"status": "active",
"created": "2020-05-25T14:36:04.363353Z",
"documents": [],
"collection": null,
"loss_payee": "Not applicable"
}
]
}
List all previously created policies
View policy
Request
GET /v1/policies/<policy_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET \
--url https://api-sandbox.hokodo.co/v1/policies/<policy_id> \
--header "Authorization: <your_api_key>"
}"
Responses
- regular response
200 Ok
Content-Type: application/json
{
"url": "https://api-sandbox.hokodo.co/v1/policies/pol-V3h9nZQWDj9pxXWgkSjq8k",
"id": "pol-V3h9nZQWDj9pxXWgkSjq8k",
"number": "T-F9BE-13AF",
"quote": "quo-YFaytjhqTD6ahBvjZdd5bV",
"status": "active",
"created": "2020-05-25T14:36:04.363353Z",
"documents": [],
"collection": null,
"loss_payee": "Not applicable"
}
- not found
404 Not Found
Content-Type: application/json
{
"detail": "Not found."
}
Retrieve a previously created policy
Errors
errors | description |
---|---|
404 | the policy id is probably incorrect, a policy has not been found |
Collections and claims
If an insured invoice doesn't get paid past a certain date, the user can hand it over to Hokodo. We will then try to collect, and if that is unsuccessful pay a claim.
To hand over an unpaid invoice to collections, you create a Collection
object, attached to a Policy
.
Collections are identified by a unique, random ID.
The collection object will be pre-filled with known information about the creditor and the debtor. That information can still be modified by the customer, for example to indicate the address of the proper branch of the debtor company to contact, or the right contact person.
Some documents must be attached to the collection request, for example a copy of the original invoice. To do so, create a CollectionDocument
object.
Once a Collection
object is created and attached to a policy, it cannot be attached to a different policy.
Once a collection request has been sent, the object cannot be modified anymore (this rule may be relaxed in the future) and documents attached to it cannot be deleted through the API.
Collection endpoints
Collections:
POST /v1/collections
GET /v1/collections
GET /v1/collections/<collection_id>
PATCH /v1/collections/<collection_id>
PUT /v1/collections/<collection_id>/send
Collection documents:
POST /v1/collectiondocuments
GET /v1/collectiondocuments
GET /v1/collectiondocuments/?policy_id=<policy_id>
GET /v1/collectiondocuments/<document_id>
DELETE /v1/collectiondocuments/<document_id>
Collection object
{
"id": "coll-TWyj6XFLYfCnw95KgBhHDf",
"policy": "pol-WwX8y7hKWyje2ttm6nAbvU",
"created": "2019-06-18T10:56:05.933635Z",
"modified": "2019-06-26T08:42:34.254546Z",
"sent": "2019-06-26T08:42:33.069006Z",
"confirm_correct": true,
"confirmed_correct": "2019-06-26T08:42:32.388611Z",
"collections_terms_acceptance": true,
"accepted_collections_terms": "2019-06-26T08:42:32.388621Z",
"collect_fees_from_debtor": true,
"creditor_contact_name": "This Is Me",
"creditor_contact_email": "realuser@usercompany.com",
"creditor_contact_phone": "+441234567890",
"debtor_address": "1 Bad Payer Street, London, E2 8AA",
"debtor_postcode": "E2 8AA",
"debtor_city": "London",
"debtor_country": "GB",
"debtor_contact_name": "Mean Buyer",
"debtor_contact_email": "mean@buyer.com",
"debtor_contact_phone": "+440987654321",
"debtor_website": "",
"bank_account_name": "User Company",
"bank_account_sortcode": "12-10-24",
"bank_account_number": "80804040",
"bank_account_email": "accounts@usercompany.com",
"actions_taken": "",
"partial_payment": "0.00",
"disputed": false,
"other_invoices": false,
"reasons": "",
"comments": ""
}
field | type | flags | description |
---|---|---|---|
id | string(uuid) | read-only | API identifier of the collection |
policy | string(uuid) | required | API identifier of the linked policy |
created | datetime | read-only | Created time |
modified | datetime | read-only | Last modified time |
sent | datetime | read-only | Timestamp at which the collection request has been sent |
confirm_correct | boolean | optional | Customer has confirmed the information is correct (Cannot be set at creation) |
confirmed_correct | datetime | read-only | Timestamp of confirm_correct true |
collections_terms_acceptance | boolean | optional | Customer has accepted the collections terms and conditions (Cannot be set at creation) |
accepted_collections_terms | datetime | read-only | Timestamp of collections_terms_acceptance true |
collect_fees_from_debtor | boolean | optional | Should the collection fees be collected from debtor? |
creditor_contact_name | string | optional | Creditor contact name (defaults to the user's name) |
creditor_contact_email | string(email) | optional | Creditor contact email address (defaults to the user's email address) |
creditor_contact_phone | string | optional | Creditor contact phone number (defaults to the user's phone if available) |
debtor_address | string | optional | Debtor address |
debtor_postcode | string | optional | Debtor postal/zip code |
debtor_city | string | optional | Debtor city |
debtor_country | country | optional | Debtor country (ISO 3166-1 2 letter code) |
debtor_contact_name | string | optional | Debtor contact name |
debtor_contact_email | string(email) | optional | Debtor contact email address |
debtor_contact_phone | string | optional | Debtor contact phone number |
debtor_website | string | optional | Debtor website |
bank_account_name | string | optional | Name on the bank account |
bank_account_sortcode | string | optional | Bank account sortcode |
bank_account_number | string | optional | Bank account number |
bank_account_email | string(email) | optional | Email address of person checking the bank account |
actions_taken | string | optional | Actions already taken by the creditor |
partial_payment | decimal | optional | Partial payment received (defaults to 0) |
disputed | boolean | optional | Is the invoice disputed by the debtor? (defaults to false) |
other_invoices | boolean | optional | Are there other outstanding invoices with this debtor? (defaults to false) |
reasons | string | optional | Non-payment reasons if known |
comments | string | optional | Other comments and instructions |
Create a collection
Request
POST /v1/collections HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"policy": "pol-WwX8y7hKWyje2ttm6nAbvU"
}
curl --request POST
--url https://api-sandbox.hokodo.co/v1/collections/ \
--header 'Authorization: Token <your_api_key>' \
--header 'Content-Type: application/json' \
--data-binary "{
\"policy\": \"pol-WwX8y7hKWyje2ttm6nAbvU\"
}"
Response
- regular response
201 Created
Content-Type: application/json
{
"id": "coll-e8rkfpHNMyCoaL6MNab8sP",
"created": "2020-05-28T13:47:05.086201Z",
"modified": "2020-05-28T13:47:05.120969Z",
"sent": null,
"creditor_contact_name": "",
"creditor_contact_email": "johnny@hokodo.co",
"creditor_contact_phone": "",
"debtor_address": "1 Some Street, London, SE11 6NQ",
"debtor_postcode": "SE11 6NQ",
"debtor_city": "London",
"debtor_country": "GB",
"debtor_contact_name": "",
"debtor_contact_email": "",
"debtor_contact_phone": "",
"debtor_website": "",
"actions_taken": "",
"partial_payment": "0.00",
"disputed": false,
"other_invoices": false,
"reasons": "",
"comments": "",
"bank_account_name": "Some Company LLC",
"bank_account_sortcode": "",
"bank_account_number": "",
"bank_account_email": "johnny@hokodo.co",
"confirmed_correct": null,
"accepted_collections_terms": null,
"collect_fees_from_debtor": null,
"policy": "pol-bX9R96pziJSs6774VkpmCR"
}
- error response (incorrect policy status)
409 Conflict
Content-Type: application/json
{
"detail": "Collection request not available in this policy status"
}
To create a collection request, you create a Collection
object attached to the Policy
of the unpaid invoice.
A Policy
has to be in the state late_can_handover
for a collection request to be possible. The policy reaches that state automatically depending on the due date and the terms of the insurance (how soon can a customer hand over the invoice after the due date). Trying to start or modify a collection request in another state will result in an HTTP 409 error in the response.
Organisation, which owns the invoice, must have at least one admin user to create collection requests.
Errors
errors | description |
---|---|
400 | a required field is missing or some of the fields have incorrect value |
409 | current policy status does not allow creation of collection requests |
View collection
Request
GET /v1/collections/<collection_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET
--url https://api-sandbox.hokodo.co/v1/collections/ \
--header 'Authorization: Token <your_api_key>'
Response
200 Ok
Content-Type: application/json
{
"id": "coll-e8rkfpHNMyCoaL6MNab8sP",
"created": "2020-05-28T13:47:05.086201Z",
"modified": "2020-05-28T13:47:05.120969Z",
"sent": null,
"creditor_contact_name": "",
"creditor_contact_email": "johnny@hokodo.co",
"creditor_contact_phone": "",
"debtor_address": "1 Some Street, London, SE11 6NQ",
"debtor_postcode": "SE11 6NQ",
"debtor_city": "London",
"debtor_country": "GB",
"debtor_contact_name": "",
"debtor_contact_email": "",
"debtor_contact_phone": "",
"debtor_website": "",
"actions_taken": "",
"partial_payment": "0.00",
"disputed": false,
"other_invoices": false,
"reasons": "",
"comments": "",
"bank_account_name": "Some Company LLC",
"bank_account_sortcode": "",
"bank_account_number": "",
"bank_account_email": "johnny@hokodo.co",
"confirmed_correct": null,
"accepted_collections_terms": null,
"collect_fees_from_debtor": null,
"policy": "pol-bX9R96pziJSs6774VkpmCR"
}
Retrieve a single previously created collection request.
Errors
errors | description |
---|---|
404 | the collection_id is probably invalid, the collection has not been found |
Update collection request
Request
PATCH /v1/collections/<collection_id> HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
{
"creditor_contact_phone": "+441234567890",
"debtor_contact_name": "Mean Buyer",
"debtor_contact_email": "mean@buyer.com",
"debtor_contact_phone": "+440987654321",
"confirm_correct": true,
"collections_terms_acceptance": true,
"collect_fees_from_debtor": false
}
curl --request PATCH \
--url https://api-sandbox.hokodo.co/v1/collections/coll-TWyj6XFLYfCnw95KgBhHDf \
--header 'Authorization: Token <your_api_key>' \
--header 'Content-Type: application/json' \
--data '{
"creditor_contact_phone": "+441234567890",
"debtor_contact_name": "Mean Buyer",
"debtor_contact_email": "mean@buyer.com",
"debtor_contact_phone": "+440987654321",
"confirm_correct": true,
"collections_terms_acceptance": true,
"collect_fees_from_debtor": false
}'
Response
200 Ok
Content-Type: application/json
{
"id": "coll-e8rkfpHNMyCoaL6MNab8sP",
"confirm_correct": true,
"collections_terms_acceptance": true,
"created": "2020-05-28T13:47:05.086201Z",
"modified": "2020-05-28T13:54:50.902225Z",
"sent": null,
"creditor_contact_name": "",
"creditor_contact_email": "johnny@hokodo.co",
"creditor_contact_phone": "+441234567890",
"debtor_address": "1 Some Street, London, SE11 6NQ",
"debtor_postcode": "SE11 6NQ",
"debtor_city": "London",
"debtor_country": "GB",
"debtor_contact_name": "Mean Buyer",
"debtor_contact_email": "mean@buyer.com",
"debtor_contact_phone": "+440987654321",
"debtor_website": "",
"actions_taken": "",
"partial_payment": "0.00",
"disputed": false,
"other_invoices": false,
"reasons": "",
"comments": "",
"bank_account_name": "Some Company LLC",
"bank_account_sortcode": "",
"bank_account_number": "",
"bank_account_email": "johnny@hokodo.co",
"confirmed_correct": "2020-05-28T13:54:50.902013Z",
"accepted_collections_terms": "2020-05-28T13:54:50.902022Z",
"collect_fees_from_debtor": false,
"policy": "pol-bX9R96pziJSs6774VkpmCR"
}
Update a collection request.
Errors
errors | description |
---|---|
400 | a required field is missing or some of the fields have incorrect value |
404 | the collection_id is probably invalid, the collection has not been found |
CollectionDocument object
{
"id": "cdoc-afipG98cKcQL5VRjVfPP2S",
"policy": "pol-WwX8y7hKWyje2ttm6nAbvU",
"type": "invoice",
"description": "",
"file": "https://hokodo-sandbox-clientdocuments.s3.amazonaws.com/media/user_uploaded_documents/..."
}
field | type | flags | description |
---|---|---|---|
id | string(uuid) | read-only | API unique identifier of the collection document |
policy | string(uuid) | required | API identifier of the linked policy |
type | string | optional | Type of document, see below |
description | string | optional | Description of the document |
file | string(uri) | read-only | Link to the document |
CollectionDocument type
Possible collection document types are:
invoice
statement
(statement of account)prood_order
(proof of order, contract of sale)proof_delivery
(proof and terms of delivery)shipping
(shipping documnents)correspondence
(recent correspondence)other
Create a collection document
POST /v1/collectiondocuments HTTP/1.1
Host: api-sandbox.hokodo.co
Content-Type: multipart/form-data; boundary=X-CLIENT-BOUNDARY
Authorization: Token <your_api_key>
Accept: */*
Content-Length: <some_length>
curl --request POST \
--url https://api-sandbox.hokodo.co/v1/collectiondocuments \
--header 'Authorization: Token <your_api_key>' \
--form policy=pol-WwX8y7hKWyje2ttm6nAbvU \
--form type=invoice \
--form file=@/path/to/file
To create a collection document, you create a CollectionDocument
object attached to the Policy
of the unpaid invoice.
Send a collection request
PUT /v1/collections/<collection_id>/send HTTP/1.1
Authorization: Token <your_api_key>
curl --request PUT \
--url https://api-sandbox.hokodo.co/v1/collections/coll-TWyj6XFLYfCnw95KgBhHDf/send/ \
--header 'Authorization: Token <your_api_key>'
Once all the information has been filled in correctly, calling this hands over the collection request to our collections partner.
Notes and possible causes of error
A Policy
has to be in the state late_can_handover
for a collection request to be possible. The policy reaches that state automatically depending on the due date and the terms of the insurance (how soon can a customer hand over the invoice after the due date). Trying to start or modify a collection request in another state will result in an HTTP 409 error in the response.
When a policy is insured, it will go in the following states:
active
: the invoice has been insured, and the invoice is not due yet.late
: the invoice is insured and due, the customer or the platform hasn't indicated it has been paid yet.paid
: the customer has indicated the invoice has been paid, the policy is now inactive.late_can_handover
: the invoice is insured and due, and has reached the date the customer can hand it over for collections and claims. From this point in time the customer has a limited time (typically 30 days) to hand it over, and should be reminded either by our emails or your notifications to either hand it over or mark the invoice as paid.lapsed
: the policy has lapsed with the customer neither handing it over to collections nor marking it as paid.under_collection
: the invoice has been handed over by the customer for collections and claims.
There are a number of additional states after a policy goes through the collections and claims process, that can be useful to display the current status of collections to the users.
Collection
under_collection
: Under collectionpay_installments
: Collection by installmentsnot_collectable
: Not collectablenot_collectable_dispute
: Not collectable due to disputeunder_collection_installments
: Under collection by installmentsdispute_pursual
: Dispute pursualunder_collection_dispute_solved
: Under collection, dispute has been solved
Claim
claim_submitted
: Claim submittedclaim_approved
: Claim approvedclaim_rejected
: Claim rejectedrecovery_installments
: Recovery by installmentsrecovery_underway
: Recovery underwayrecovery_complete
: Recovery completerecovery_rejected
: Recovery rejected
Webhooks
Sample content
Active insurance policy
policy
is filledquote.status
isaccepted
{
"url": "https://api-sandbox.hokodo.co/v1/transactions/trns-5DpFHDgVpv87wJFa9dXyvW",
"id": "trns-5DpFHDgVpv87wJFa9dXyvW",
"owner": "user-MzPbafH78Byb65U7PshRpF",
"debtor": "co-Tv5pezgn7VAYEbLXfexbS2",
"debtor_name": "Test debtor",
"debtor_country": "GB",
"debtor_regnum": "",
"debtor_address": "",
"creditor": "co-WUaZHXbdsbAvxpYbBPhYh8",
"creditor_name": "Test creditor",
"creditor_country": "GB",
"creditor_regnum": "",
"creditor_address": "",
"status": "pending",
"pay_method": "unknown",
"net_amount": "1234.00",
"gross_amount": null,
"currency": "GBP",
"issue_date": "2019-10-16",
"due_date": "2019-12-16",
"paid_date": null,
"number": "",
"items": [],
"source": null,
"unique_id": "",
"policy": {
"url": "https://api-sandbox.hokodo.co/v1/policies/pol-4wvXe9URiecFYiLxuXkkxf",
"id": "pol-4wvXe9URiecFYiLxuXkkxf",
"number": "T-4ZW5-611D",
"status": "active",
"created": "2019-11-07T11:17:40.451738Z",
"documents": [
{
"category": "policy",
"url": "https://removed.for.this.example"
}
],
"collection": null,
"loss_payee": "Not applicable"
},
"quote": {
"url": "https://api-sandbox.hokodo.co/v1/quotes/quo-jaetYa8f9TmFDBYsb33KAT",
"id": "quo-jaetYa8f9TmFDBYsb33KAT",
"client": {
"url": "https://api-sandbox.hokodo.co/v1/companies/co-WUaZHXbdsbAvxpYbBPhYh8",
"id": "co-WUaZHXbdsbAvxpYbBPhYh8",
"country": "GB",
"name": "Test creditor Limited",
"address": "123 Main Street, City, County, Region, Postcode",
"city": "Test city",
"postcode": "Test postcode",
"legal_form": "Private limited with share capital",
"sectors": [
{
"system": "SIC2007",
"code": "47710"
}
],
"creation_date": "1995-07-12",
"identifiers": [
{
"idtype": "reg_number",
"country": "GB",
"value": "01234567"
}
],
"email": "",
"phone": "",
"status": "Active",
},
"status": "accepted",
"proposed_quote": null,
"rejection_reason": null,
"created": "2019-11-07T11:17:38.166454Z",
"valid_until": "2019-11-07T13:17:38.158274Z",
"price": {
"currency": "GBP",
"total_price": "20.45",
"premium": "18.26",
"ipt": "2.19"
},
"insured": {
"currency": "GBP",
"insured_amount": "1110.60"
},
"insured_pc_net": 90.0,
"insured_pc_gross": null,
"referral_url": null
},
"estimated_quote_price": null
}
Quote, but no insurance policy purchased
policy
isnull
quote.status
isoffered
{
"url": "https://api-sandbox.hokodo.co/v1/transactions/trns-5DpFHDgVpv87wJFa9dXyvW",
"id": "trns-5DpFHDgVpv87wJFa9dXyvW",
"owner": "user-MzPbafH78Byb65U7PshRpF",
"debtor": "co-Tv5pezgn7VAYEbLXfexbS2",
"debtor_name": "Test debtor",
"debtor_country": "GB",
"debtor_regnum": "",
"debtor_address": "",
"creditor": "co-WUaZHXbdsbAvxpYbBPhYh8",
"creditor_name": "Test creditor",
"creditor_country": "GB",
"creditor_regnum": "",
"creditor_address": "",
"status": "pending",
"pay_method": "unknown",
"net_amount": "1234.00",
"gross_amount": null,
"currency": "GBP",
"issue_date": "2019-10-16",
"due_date": "2019-12-16",
"paid_date": null,
"number": "",
"items": [],
"source": null,
"unique_id": "",
"policy": null,
"quote": {
"url": "https://api-sandbox.hokodo.co/v1/quotes/quo-jaetYa8f9TmFDBYsb33KAT",
"id": "quo-jaetYa8f9TmFDBYsb33KAT",
"client": {
"url": "https://api-sandbox.hokodo.co/v1/companies/co-WUaZHXbdsbAvxpYbBPhYh8",
"id": "co-WUaZHXbdsbAvxpYbBPhYh8",
"country": "GB",
"name": "Test creditor Limited",
"address": "123 Main Street, City, County, Region, Postcode",
"city": "Test city",
"postcode": "Test postcode",
"legal_form": "Private limited with share capital",
"sectors": [
{
"system": "SIC2007",
"code": "47710"
}
],
"creation_date": "1995-07-12",
"identifiers": [
{
"idtype": "reg_number",
"country": "GB",
"value": "01234567"
}
],
"email": "",
"phone": "",
"status": "Active",
},
"status": "offered",
"proposed_quote": null,
"rejection_reason": null,
"created": "2019-11-07T11:17:38.166454Z",
"valid_until": "2019-11-07T13:17:38.158274Z",
"price": {
"currency": "GBP",
"total_price": "20.45",
"premium": "18.26",
"ipt": "2.19"
},
"insured": {
"currency": "GBP",
"insured_amount": "1110.60"
},
"insured_pc_net": 90.0,
"insured_pc_gross": null,
"referral_url": null
},
"estimated_quote_price": null
}
No valid quote, nor insurance policy
policy
isnull
quote.status
isnull
{
"url": "https://api-sandbox.hokodo.co/v1/transactions/trns-5DpFHDgVpv87wJFa9dXyvW",
"id": "trns-5DpFHDgVpv87wJFa9dXyvW",
"owner": "user-MzPbafH78Byb65U7PshRpF",
"debtor": "co-Tv5pezgn7VAYEbLXfexbS2",
"debtor_name": "Test debtor",
"debtor_country": "GB",
"debtor_regnum": "",
"debtor_address": "",
"creditor": "co-WUaZHXbdsbAvxpYbBPhYh8",
"creditor_name": "Test creditor",
"creditor_country": "GB",
"creditor_regnum": "",
"creditor_address": "",
"status": "pending",
"pay_method": "unknown",
"net_amount": "1234.00",
"gross_amount": null,
"currency": "GBP",
"issue_date": "2019-10-16",
"due_date": "2019-12-16",
"paid_date": null,
"number": "",
"items": [],
"source": null,
"unique_id": "",
"policy": null,
"quote": null,
"estimated_quote_price": null
}
Hokodo can send webhook events to notify your application when an event related to a quote or active policy happens. This is useful for example for events that are triggered by a user action outside of your application, or events that are triggered at a certain point in time on our side. For example, but not limited to:
- user accepts a quote and proceeds to buy a policy on our website,
- a new quote is offered,
- an invoice is marked as settled,
- ...
It allows you to avoid polling the quote view endpoint and be notified instead. It is entirely optional. If you wish to use this feature, please let us know at partner-support@hokodo.co and we will be happy to configure your account.
Concepts
Currently the webhooks cover changes related to the Transaction
, Quote
and Policy
objects.
Your callback endpoint will receive the Transaction
object representation, in expanded form to include the latest quote or policy attached to the transaction. Hokodo calls your endpoint with the content of the transaction, as you would get if you were polling GET /v1/transactions/:transaction-id/?expand=quote,policy
.
What you need to build on your side is an endpoint ready to receive our requests, with that expanded Transaction
in the body. Provide us with:
- the URL of that endpoint
- (optional) an authentication string our webhook will send in the
Authorization
header
Notes
Your endpoint must be using HTTPS.
In production, our API will verify the validity of the HTTPS certificate. In sandbox, you can use a self-signed certitificate.
Our API will send a POST request, with the content of the
Transaction
in the POST request body as JSON.Our API expects a
2xx
status code from your endpoint for a successful response.Our API will retry up to 3 times if it can't connect successfully to your endpoint. It will wait 0, 2, and 4 seconds respectively before the 1st, 2nd and 3rd retry.
Events of interest
If a quote has been offered and the customer has purchased an insurance policy, both the quote
and policy
field in the transaction JSON will be filled and expanded. What will probably be of most interest to you then is looking at the quote
and policy
fields in the webhook request body.
"policy": null, "quote": null
means no quote and no policy,"policy": null, "quote": {...}
means there is a quote and no policy has been purchased, you can check"status"
in the quote sub-object to know if it is offered, declined or expired."policy": {...}, "quote": {...}
means a policy has been purchased.
Errors
The Hokodo API uses the following error codes:
Error Code | Meaning |
---|---|
400 | Bad Request -- Your request is invalid. |
401 | Unauthorized -- Your API key is wrong. |
403 | Forbidden -- The requested function is not available for your account. |
404 | Not Found -- The specified object could not be found. |
405 | Method Not Allowed -- You tried to access an object with an invalid method. |
409 | Conflict -- The requested action conflicts with the current state of the object. |
500 | Internal Server Error -- We had a problem with our server. Try again later. |
503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |