Skip to main content

InCountry REST API documentation

Welcome to the InCountry REST API reference documentation. You can use this REST API to build apps for taking advantage of data residency services provided by InCountry. This page documents the REST resources provided by the InCountry platform, along with the expected HTTP response codes and sample requests.

Overview

The InCountry REST API is a set of RESTful methods that allow you to query regulated data from the InCountry platform without integrating the InCountry SDK into your application. It simplifies data communication and lets you quickly build applications with data localization capabilities.

The data flow diagram is shown below:

REST API Diagram

Authentication and authorization

The InCountry REST API uses OAuth2 to authenticate and authorize requests with access tokens that are issued by the authentication server. To get a token, you need to create a REST API integration on the InCountry Portal and use the generated Client ID and Client Secret to get an access token for authorizing your data communication requests.

Requesting a token

POST https://{{oauth_endpoint}}/oauth2/token

Instead of the {oauth_endpoint} part, enter the address of the OAuth server depending on the region where the country is located.

  • EMEA: https://auth-emea.incountry.com/

  • APAC: https://auth-apac.incountry.com/

note

EMEA unites countries located in Europe, the Middle East, and Africa.

APAC unites countries located in the region around the Western Pacific Ocean.

TO FIND OUT THE APPROPRIATE OAUTH SERVER FOR YOUR COUNTRY, PLEASE CHECK THIS PAGE.

As authorization credentials, you need to pass the Client ID (as username) and Client Secret (as password) that you received on the InCountry Portal. The authorization type should be basic authorization. It will transform authorization credentials into Base64 format.

Within the request body, you need to pass additional keys:

KeyValueDescription
grant_typeclient_credentials
audienceFor example:
https://se-restapi-mt-01.api.incountry.io https://se-mt-01.api.incountry.io
You need to pass the address of the REST API server. It will be provided by the InCountry Portal when you create an integration of the restapi type.

Such address looks like:

https://{{country_code}}-restapi-mt-01.api.incountry.io

Besides, the address of a REST API server you need to pass the address of the Point-of-Presence within the same country when a REST API server is located.

Such address looks like:

https://{{country_code}}-mt-01.api.incountry.io
scopeFor example:
f2e5a966-1564-4c25-a3bf-0ef7a231fb2b
Identifier of the environment within the target country. The environment ID should correspond to the authorization credentials (Client ID and Client Secret).
Warning

If the request to issue an OAuth token does not include both the REST API URL and PoP API URL, then you will get the Storage authentication error.

cURL request

note

For the audience parameter, please use the appropriate endpoint that you receive upon the creation of the REST API integration.

curl --location --request POST
--url 'https://{oauth_endpoint}/oauth2/token' \
--header 'Authorization: Basic base64{your_client_id:your_client_secret}' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'audience={rest_api_address popapi_address)' \
--data-urlencode 'scope={your_environment_id}'
note

For the Authorization part, you need to encode the {client_id:client_secret} string into a base64 string. For example, after appending Client Secret to Client ID, you should get something like this:

2681cad2-61a2-467f-a82c-a974e6d891e9:SGmdEj6plYd5nSeY-b-NHmCX3f

After base64 encoding this string, will look like this:

MjY4MWNhZDItNjFhMi00NjdmLWE4MmMtYTk3NGU2ZDg5MWU5OlNHbWRFajZwbFlkNW5TZVktYi1OSG1DWDNm

For testing purposes on non-production data, you can use the following service for base64 encoding.

As a response from the oAuth server, you will receive the following:

  • access token - token string.

  • expires_in - life span of a generated token in seconds before it expires.

  • scope - environment ID.

  • token_type - bearer.

Once you have received the access token, use it for data management requests that you perform.

note

The access token is valid for 300 seconds, then it expires. You need further to get a new token by following the same approach.

Data Encryption

InCountry REST API is using the AES-GCM encryption with a 256-bit AES key and a 96-bit nonce.

URI structure

InCountry REST API provides access to resources (like data entities) via URI paths. To use REST API, your application makes an HTTP request and parse the response.

InCountry REST API uses JSON as its communication format and the standard HTTP methods like POST , GET, and DELETE. URIs for the InCountry REST API resources have the following structure:

//For record management:
https://{host}/api/records/{resource-name}

//For attachment management:
https://{host}/api/records/{country}/{key}/files/{fileId}

Getting started with REST API

To get started with the REST API, you can download the Postman collection of requests. You can use this collection to perform test requests and queries to the InCountry platform.

  1. Create a new REST integration on the InCountry Portal.

  2. Download the Postman collection and import it into the application.

  3. Add your Client ID and Client Secret into the token acquiring request.

  4. Perform data communication requests with regulated data.

REST API resources

Below you can find the available API resources within the InCountry REST API.

Management of records

You can manage records within the InCountry Platform, as follows:

Available record fields

All records saved to InCountry Platform may have the following fields:

FieldTypeStorageSpecifics
record_keystringHashedThis is a unique identifier of the record which is returned by the REST API. This field is used to store the primary key of the record. This field is used as an alias for the deprecated key field.
bodystringEncryptedYou can also stringify data in the JSON format and save it within this field.
precommit_bodystringEncryptedYou can use this field to store some service information about the record.
profile_keystringHashedThe unique identifier of the data record in an external system. It can be used for storing any other data string if needed.
parent_keystringHashedKey of the parent record which the current record is attributed to.
range_keyNintegerPlainN can be between 1 … 10. You can use up to 10 fields. The range_keyN fields are used for value range filtration of numerical values.
service_keyNstringHashedN can take from 1 to 5. You can have up to 5 fields. The service_keyN fields can be used for storing additional text information.
keyNstringHashed / PlainN can take from 1 to 20. You can use up to 20 fields. This value can be hashed or remain as a plain value depending on your configuration. This field can be used for record lookup.
created_atstring (date-time)PlainThe timestamp in the ISO-8601 format when a record was created.
updated_atstring (date-time)PlainThe timestamp in the ISO-8601 format when a record was updated.
expires_atstring (date-time)PlainThis field determines the date and time when the record will be automatically deleted from the InCountry platform.
countryISO country code (lowercase)PlainCountry where a new record is stored.
attachmentsobject-For the details on the attachments field, please see the Management of attachments section.

Creating a single record

POST /api/records

note

Alternatively, this request can be used to update the record. Be careful, as it rewrites the data record with new values you provide.

Request body

Please see the example of the request structure.

Example:

{
"key": "string",
"record_key": "string",
"body": "string / string in the JSON format",
"precommit_body": "string",
"profile_key": "string",
"parent_key": "string",
"range_key": 0,
"range_key1": 0,
"range_key2": 0,
"range_key3": 0,
"range_key4": 0,
"range_key5": 0,
"range_key6": 0,
"range_key7": 0,
"range_key8": 0,
"range_key9": 0,
"range_key10": 0,
"service_key1": "string",
"service_key2": "string",
"service_key3": "string",
"service_key4": "string",
"service_key5": "string",
"key1": "string",
"key2": "string",
"key3": "string",
"key4": "string",
"key5": "string",
"key6": "string",
"key7": "string",
"key8": "string",
"key9": "string",
"key10": "string",
"key11": "string",
"key12": "string",
"key13": "string",
"key14": "string",
"key15": "string",
"key16": "string",
"key17": "string",
"key18": "string",
"key19": "string",
"key20": "string",
"expires_at": "2021-04-07T07:15:44.393Z",
"country": "string"
}
note

The country code is defined by the Rest API instance. For one instance, you can use only one country code. For example, for https://se-restapi-mt-01.incountry.io it can only be se.

cURL request
curl --request POST \
--url 'https://{restApiURLAddress}/api/records' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"record_key": "d1c2e12cfeababc8b95daf6902e210b1",
"profile_key": "4274e510a2f41aeb9e8e0f8b56ff6c2",
"range_key": 2000,
"key10": "New",
"key9": null,
"key8": null,
"key7": null,
"key6": null,
"key5": null,
"key4": "Shipping",
"key3": null,
"key2": null,
"key1": "Additional info",
"key": null,
"body": "{\"name\":\"John\",\"vehicle\":\"Audi\"}",
"country": "se"
}'
Responses

STATUS 201 - application/json Returns information and a record key for the newly created record. The InCountry platform will return the record data with information similar to the data you submitted within the request.

{
"country": "se",
"key": "d1c2e12cfeababc8b95daf6902e210b1",
"record_key": "d1c2e12cfeababc8b95daf6902e210b1",
"profile_key": "4274e510a2f41aeb9e8e0f8b56ff6c2",
"range_key": 2000,
"range_key1": 2000,
"body": "{\"name\":\"John\",\"vehicle\":\"Audi\"}",
"key1": "Additional info",
"key2": null,
"key3": null,
"key4": "Shipping",
"key5": null,
"key6": null,
"key7": null,
"key8": null,
"key9": null,
"key10": "New"
}

STATUS 400 - application/json Failed request that has not passed validation. The error details will be in the response.

STATUS 401 - This error status is returned when the request is unauthorized.

STATUS 5** - Server error.

Updating a single record

POST /api/records

note

You can use this request to update the existing records. You need to pass new values for fields that you want to modify, along with old values for fields that you do not want to modify. This request will overwrite the current record’s values with new ones, so if you do not provide old values for specific fields, values in such fields will be cleared.

For the details on this request body, please see the Create a single record request.

cURL request

curl --request POST \
--url 'https://{restApiURLAddress}/api/records' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"record_key": "d1c2e12cfeababc8b95daf6902e210b1",
"profile_key": "4274e510a2f41aeb9e8e0f8b56ff6c2",
"range_key": 2000,
"key10": "New",
"key9": "Position",
"key8": "Product Manager",
"key7": null,
"key6": null,
"key5": null,
"key4": "Shipping",
"key3": null,
"key2": null,
"key1": "Additional info",
"key": null,
"body": "{\"name\":\"John\",\"vehicle\":\"Audi\"}",
"country": "se",
"expires_at": "2021-04-07T07:15:44.393Z"
}'

Responses

STATUS 201 - application/json Returns information and a record key for the newly created record. The InCountry platform will return the record data with information similar to the data you submitted within the request.

{
"country": "se",
"key": "d1c2e12cfeababc8b95daf6902e210b1",
"record_key": "d1c2e12cfeababc8b95daf6902e210b1",
"profile_key": "4274e510a2f41aeb9e8e0f8b56ff6c2",
"range_key": 2000,
"range_key1": 2000,
"body": "{\"name\":\"John\",\"vehicle\":\"Audi\"}",
"key1": "Additional info",
"key2": "Position",
"key3": "Product Manager",
"key4": "Shipping",
"key5": null,
"key6": null,
"key7": null,
"key8": null,
"key9": null,
"key10": "New",
"expires_at": "2021-04-07T07:15:44.393Z"
}

STATUS 400 - application/json Failed request that has not passed validation. The error details will be in the response.

STATUS 401 - This error status is returned when the request is unauthorized.

STATUS 5** - Server error.

Creating multiple records

POST /api/records/batch

Request body

Please see the example of the request structure.

Example:

{
"country": "string",
"records": [
{
"key": "string",
"record_key": "string",
"body": "string / string in the JSON format",
"precommit_body": "string",
"profile_key": "string",
"parent_key": "string",
"range_key": 0,
"range_key1": 0,
"range_key2": 0,
"range_key3": 0,
"range_key4": 0,
"range_key5": 0,
"range_key6": 0,
"range_key7": 0,
"range_key8": 0,
"range_key9": 0,
"range_key10": 0,
"service_key1": "string",
"service_key2": "string",
"service_key3": "string",
"service_key4": "string",
"service_key5": "string",
"key1": "string",
"key2": "string",
"key3": "string",
"key4": "string",
"key5": "string",
"key6": "string",
"key7": "string",
"key8": "string",
"key9": "string",
"key10": "string",
"key11": "string",
"key12": "string",
"key13": "string",
"key14": "string",
"key15": "string",
"key16": "string",
"key17": "string",
"key18": "string",
"key19": "string",
"key20": "string",
"expires_at": "2021-04-07T07:15:44.435Z"
},
{
"key": "string",
"record_key": "string",
"body": "string / string in the JSON format",
"precommit_body": "string",
"profile_key": "string",
"parent_key": "string",
"range_key": 0,
"range_key1": 0,
"range_key2": 0,
"range_key3": 0,
"range_key4": 0,
"range_key5": 0,
"range_key6": 0,
"range_key7": 0,
"range_key8": 0,
"range_key9": 0,
"range_key10": 0,
"service_key1": "string",
"service_key2": "string",
"service_key3": "string",
"service_key4": "string",
"service_key5": "string",
"key1": "string",
"key2": "string",
"key3": "string",
"key4": "string",
"key5": "string",
"key6": "string",
"key7": "string",
"key8": "string",
"key9": "string",
"key10": "string",
"key11": "string",
"key12": "string",
"key13": "string",
"key14": "string",
"key15": "string",
"key16": "string",
"key17": "string",
"key18": "string",
"key19": "string",
"key20": "string",
"expires_at": "2021-04-07T07:15:44.435Z"
}
]
}

cURL request

curl --request POST \
--url 'https://{restApiURLAddress}/api/records/batch' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"records": [
{
"record_key": "d1c2e12cfeababc8b95daf6902e210b1",
"profile_key": "4274e510a2f41aeb9e8e0f8b56ff6c2",
"range_key": 2000,
"key10": "New",
"key9": null,
"key8": null,
"key7": null,
"key6": null,
"key5": null,
"key4": "Shipping",
"key3": null,
"key2": null,
"key1": "Additional info",
"key": null,
"body": "{\"name\":\"John\",\"vehicle\":\"Audi\"}"
},
{
"record_key": "69f6a71405facac91d002dc9adce85fa",
"profile_key": "baab015f2f9c350ab610fddd3986c53",
"range_key": 3000,
"key10": "New",
"key9": null,
"key8": null,
"key7": null,
"key6": null,
"key5": null,
"key4": "Shipping",
"key3": null,
"key2": null,
"key1": "Additional info",
"key": null,
"body": "{\"name\":\"Alice\",\"vehicle\":\"Mercedes\"}"
}
],
"country": "se"
}'

Responses

STATUS 201 - application/json Returns information and record keys for the newly created records.

[
{
"country": "se",
"key": "d1c2e12cfeababc8b95daf6902e210b1",
"record_key": "d1c2e12cfeababc8b95daf6902e210b1",
"profile_key": "4274e510a2f41aeb9e8e0f8b56ff6c2",
"range_key": 2000,
"range_key1": 2000,
"body": "{\"name\":\"John\",\"vehicle\":\"Audi\"}",
"key1": "Additional info",
"key2": null,
"key3": null,
"key4": "Shipping",
"key5": null,
"key6": null,
"key7": null,
"key8": null,
"key9": null,
"key10": "New"
},
{
"country": "se",
"key": "69f6a71405facac91d002dc9adce85fa",
"record_key": "69f6a71405facac91d002dc9adce85fa",
"profile_key": "baab015f2f9c350ab610fddd3986c53",
"range_key": 3000,
"range_key1": 3000,
"body": "{\"name\":\"Alice\",\"vehicle\":\"Mercedes\"}",
"key1": "Additional info",
"key2": null,
"key3": null,
"key4": "Shipping",
"key5": null,
"key6": null,
"key7": null,
"key8": null,
"key9": null,
"key10": "New"
}
]

STATUS 400 - application/json Failed request that has not passed validation. The error details will be in the response.

STATUS 401 - This error status is returned when the request is unauthorized.

STATUS 5** - Server error.

Updating multiple records

POST /api/records/batch/update

Request body

Please see the example of the request structure.

{
"search_key": "record_key",
"country": "string",
"records": [
{
"key": "string",
"record_key": "string",
"body": "string / string in the JSON format",
"precommit_body": "string",
"profile_key": "string",
"parent_key": "string",
"range_key": 0,
"range_key1": 0,
"range_key2": 0,
"range_key3": 0,
"range_key4": 0,
"range_key5": 0,
"range_key6": 0,
"range_key7": 0,
"range_key8": 0,
"range_key9": 0,
"range_key10": 0,
"service_key1": "string",
"service_key2": "string",
"service_key3": "string",
"service_key4": "string",
"service_key5": "string",
"key1": "string",
"key2": "string",
"key3": "string",
"key4": "string",
"key5": "string",
"key6": "string",
"key7": "string",
"key8": "string",
"key9": "string",
"key10": "string",
"key11": "string",
"key12": "string",
"key13": "string",
"key14": "string",
"key15": "string",
"key16": "string",
"key17": "string",
"key18": "string",
"key19": "string",
"key20": "string",
"expires_at": "2021-04-07T07:15:44.435Z"
},
{
"key": "string",
"record_key": "string",
"body": "string / string in the JSON format",
"precommit_body": "string",
"profile_key": "string",
"parent_key": "string",
"range_key": 0,
"range_key1": 0,
"range_key2": 0,
"range_key3": 0,
"range_key4": 0,
"range_key5": 0,
"range_key6": 0,
"range_key7": 0,
"range_key8": 0,
"range_key9": 0,
"range_key10": 0,
"service_key1": "string",
"service_key2": "string",
"service_key3": "string",
"service_key4": "string",
"service_key5": "string",
"key1": "string",
"key2": "string",
"key3": "string",
"key4": "string",
"key5": "string",
"key6": "string",
"key7": "string",
"key8": "string",
"key9": "string",
"key10": "string",
"key11": "string",
"key12": "string",
"key13": "string",
"key14": "string",
"key15": "string",
"key16": "string",
"key17": "string",
"key18": "string",
"key19": "string",
"key20": "string",
"expires_at": "2021-04-07T07:15:46.435Z"
}
]
}

cURL request

curl --request POST \
--url 'https://{restApiURLAddress}/api/records/batch/update' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"records": [
{
"record_key": "d1c2e12cfeababc8b95daf6902e210b1",
"profile_key": "4274e510a2f41aeb9e8e0f8b56ff6c2",
"range_key": 2000,
"key10": "New",
"key9": null,
"key8": null,
"key7": null,
"key6": null,
"key5": null,
"key4": "Shipping",
"key3": null,
"key2": null,
"key1": "Additional info",
"key": null,
"body": "{\"name\":\"John\",\"vehicle\":\"Audi\"}"
},
{
"record_key": "69f6a71405facac91d002dc9adce85fa",
"profile_key": "baab015f2f9c350ab610fddd3986c53",
"range_key": 3000,
"key10": "New",
"key9": null,
"key8": null,
"key7": null,
"key6": null,
"key5": null,
"key4": "Shipping",
"key3": null,
"key2": null,
"key1": "Additional info",
"key": null,
"body": "{\"name\":\"Alice\",\"vehicle\":\"Mercedes\"}"
}
],
"country": "se"
}'

Responses

STATUS 200 - application/json Returns information and record keys of updated records.

[
{
"country": "se",
"key": "d1c2e12cfeababc8b95daf6902e210b1",
"record_key": "d1c2e12cfeababc8b95daf6902e210b1",
"profile_key": "4274e510a2f41aeb9e8e0f8b56ff6c2",
"range_key": 2000,
"range_key1": 2000,
"body": "{\"name\":\"John\",\"vehicle\":\"Audi\"}",
"key1": "Additional info",
"key2": null,
"key3": null,
"key4": "Shipping",
"key5": null,
"key6": null,
"key7": null,
"key8": null,
"key9": null,
"key10": "New"
},
{
"country": "se",
"key": "69f6a71405facac91d002dc9adce85fa",
"record_key": "69f6a71405facac91d002dc9adce85fa",
"profile_key": "baab015f2f9c350ab610fddd3986c53",
"range_key": 3000,
"range_key1": 3000,
"body": "{\"name\":\"Alice\",\"vehicle\":\"Mercedes\"}",
"key1": "Additional info",
"key2": null,
"key3": null,
"key4": "Shipping",
"key5": null,
"key6": null,
"key7": null,
"key8": null,
"key9": null,
"key10": "New"
}
]

STATUS 400 - application/json Failed request that has not passed validation. The error details will be in the response.

STATUS 401 - This error status is returned when the request is unauthorized.

STATUS 5** - Server error.

Searching for records

POST /api/records/find

Request body

ParametersTypeExampleDescription
countryISO country code (lowercase)sg - (equals to Singapore)Country where a new record is looked up. You can use different countries.
filterobjectSee the example.Specify the criteria for filtration within the filter object. You can look up records by any of record fields. For the full list of supported fields, please see the Available record fields section.
optionsobjectSee the example.Specify the criteria for returning the search results: limit, offset, and sort.
limitinteger10Sets the maximal number of search results. It is passed as a part of the options object.
offsetinteger50Specifies the offset (pagination) of records from which the record lookup is performed. It is passed as a part of the options object.
sortarraySpecifies the sorting order of records against a specific field. The sorting can be performed by the following fields: range_keyN, created_at, updated_at, and keyN. The order in which you specify fields within the sort array will affect the sorting order of records. It is passed as a part of the options object.

Please see the example of the request structure.

Example 1:

{
"country": "string",
"filter": {
"key": "string",
"record_key": "string",
"profile_key": "string",
"range_key": 0,
"range_key1": 0,
"range_key2": 0,
"range_key3": 0,
"range_key4": 0,
"range_key5": 0,
"range_key6": 0,
"range_key7": 0,
"range_key8": 0,
"range_key9": 0,
"range_key10": 0,
"key1": "string",
"key2": "string",
"key3": "string",
"key4": "string",
"key5": "string",
"key6": "string",
"key7": "string",
"key8": "string",
"key9": "string",
"key10": "string",
"key11": "string",
"key12": "string",
"key13": "string",
"key14": "string",
"key15": "string",
"key16": "string",
"key17": "string",
"key18": "string",
"key19": "string",
"key20": "string",
"service_key1": "string",
"service_key2": "string",
"service_key3": "string",
"service_key4": "string",
"service_key5": "string",
"version": 0,
"search_keys": "string"
},
"options": {
"limit": 0,
"offset": 0,
"sort": [
{
"range_key1": "asc"
},
{
"range_key2": "asc"
},
{
"range_key3": "asc"
},
{
"range_key4": "asc"
},
{
"range_key5": "asc"
},
{
"range_key6": "asc"
},
{
"range_key7": "asc"
},
{
"range_key8": "asc"
},
{
"range_key9": "asc"
},
{
"range_key10": "asc"
},
{
"created_at": "asc"
},
{
"updated_at": "asc"
},
{
"expires_at": "asc"
},
{
"key1": "asc"
},
{
"key2": "asc"
},
{
"key3": "asc"
},
{
"key4": "asc"
},
{
"key5": "asc"
},
{
"key6": "asc"
},
{
"key7": "asc"
},
{
"key8": "asc"
},
{
"key9": "asc"
},
{
"key10": "asc"
},
{
"key11": "asc"
},
{
"key12": "asc"
},
{
"key13": "asc"
},
{
"key14": "asc"
},
{
"key15": "asc"
},
{
"key16": "asc"
},
{
"key17": "asc"
},
{
"key18": "asc"
},
{
"key19": "asc"
},
{
"key20": "asc"
}
]
}
}

Example 2:

{
"country": "sg",
"filter": {
"key1": ["k1234", "k1235"],
"key2": ["John", "Jane"]
},
"options": {
"limit": 10,
"offset": 50
}
}

or

{
"country": "sg",
"filter": {
"search_keys": "abc"
}
}

or

{
"country": "sg",
"filter": {
"search_keys": "abc",
"range_key1": [1, 2]
}
}

cURL request

//FINDS A RECORD BY THE SPECIFIED CRITERIA

curl --request POST \
--url 'https://{restApiURLAddress}/api/records/find' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"country": "se",
"filter": {
"range_key": 3000,
"key4": "Shipping",
"profile_key": "baab015f2f9c350ab610fddd3986c53",
"record_key": "69f6a71405facac91d002dc9adce85fa"
},
"options": {
"limit": 10,
"offset": 0
}
}'

//FINDS RECORDS THAT HAVE THE range_key FIELD WITHIN => 1000 AND <= 4000 RANGE

curl --request POST \
--url 'https://{restApiURLAddress}/api/records/find' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"country": "se",
"filter": {
"range_key": {"$gte":1000, "$lte":4000},
"key4": "Shipping",
"profile_key": "baab015f2f9c350ab610fddd3986c53",
"record_key": "69f6a71405facac91d002dc9adce85fa"
},
"options": {
"limit": 10,
"offset": 0
}
}'

//FINDS RECORDS WHOSE THE range_key FIELD TAKES ONE OF THE SPECIFIED VALUES

curl --request POST \
--url 'https://{restApiURLAddress}/api/records/find' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"country": "se",
"filter": {
"range_key": [1000, 4000],
"key4": "Shipping",
"profile_key": "baab015f2f9c350ab610fddd3986c53",
"record_key": "69f6a71405facac91d002dc9adce85fa"
},
"options": {
"limit": 10,
"offset": 0
}
}'

//FINDS RECORDS AND SORTS THEM BY FIELD IN ASCENDING/DESCENDING ORDER

curl --request POST \
--url 'https://{restApiURLAddress}/api/records/find' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"country": "se",
"filter": {
"range_key": [1000, 4000],
"key4": "Shipping",
"profile_key": "baab015f2f9c350ab610fddd3986c53",
"record_key": "69f6a71405facac91d002dc9adce85fa"
},
"options": {
"limit": 10,
"offset": 0,
"sort":[{"key1":"asc"}, {"key2": "desc"}]
}
}'

Responses

STATUS 200 - application/json Returns information about the found record or records.

This status is also returned when no records matching the search criteria are found.

Example:

{
"data": [
{
"country": "se",
"key": "69f6a71405facac91d002dc9adce85fa",
"record_key": "69f6a71405facac91d002dc9adce85fa",
"parent_key": null,
"profile_key": "baab015f2f9c350ab610fddd3986c53",
"range_key": 3000,
"range_key1": 3000,
"range_key2": null,
"range_key3": null,
"range_key4": null,
"range_key5": null,
"range_key6": null,
"range_key7": null,
"range_key8": null,
"range_key9": null,
"range_key10": null,
"body": "{\"name\":\"Alice\",\"vehicle\":\"Mercedes\"}",
"precommit_body": null,
"key1": "Additional info",
"key2": null,
"key3": null,
"key4": "Shipping",
"key5": null,
"key6": null,
"key7": null,
"key8": null,
"key9": null,
"key10": "New",
"key11": null,
"key12": null,
"key13": null,
"key14": null,
"key15": null,
"key16": null,
"key17": null,
"key18": null,
"key19": null,
"key20": null,
"service_key1": null,
"service_key2": null,
"attachments": [],
"created_at": "2021-03-26T11:57:45.000Z",
"updated_at": "2021-03-26T11:57:45.000Z",
"version": 0
}
],
"meta": {
"count": 1,
"limit": 10,
"offset": 0,
"total": 1
}
} "updated_at": "2020-11-21T12:05:28.000Z"
}
],
"meta": {
"count": 2,
"limit": 100,
"offset": 0,
"total": 2
}
}

STATUS 400 - application/json Failed request that has not passed validation. The error details will be in the response.

STATUS 401 - This error is returned when the request is unauthorized.

Aggregating records

POST /api/records/aggregate

Please see the example of the request structure.

{
"next": "string",
"metrics": {
"additionalProp1": {
"func": "sum",
"key": "string"
},
"additionalProp2": {
"func": "sum",
"key": "string"
},
"additionalProp3": {
"func": "sum",
"key": "string"
}
},
"filter": {
"key": "string",
"record_key": "string",
"profile_key": "string",
"parent_key": "string",
"range_key": 0,
"range_key1": 0,
"range_key2": 0,
"range_key3": 0,
"range_key4": 0,
"range_key5": 0,
"range_key6": 0,
"range_key7": 0,
"range_key8": 0,
"range_key9": 0,
"range_key10": 0,
"key1": "string",
"key2": "string",
"key3": "string",
"key4": "string",
"key5": "string",
"key6": "string",
"key7": "string",
"key8": "string",
"key9": "string",
"key10": "string",
"key11": "string",
"key12": "string",
"key13": "string",
"key14": "string",
"key15": "string",
"key16": "string",
"key17": "string",
"key18": "string",
"key19": "string",
"key20": "string",
"key21": "string",
"key22": "string",
"key23": "string",
"key24": "string",
"key25": "string",
"service_key1": "string",
"service_key2": "string",
"service_key3": "string",
"service_key4": "string",
"service_key5": "string",
"version": 0,
"search_keys": "string",
"created_at": "2022-08-30T07:41:54.490Z",
"updated_at": "2022-08-30T07:41:54.490Z"
},
"group_by": {
"limit": 0,
"keys": [
"string"
]
}
}

Within the metrics section, you can define the aggregation parameters:

ArgumentDescription
additionalPropNYou can declare the aggregated metric, for example, total_sales_amount, record_count, or total_revenue.
funcYou can define the aggregation function to apply:

count - cannot take additional arguments. Counts the number of records.

sum - can take additional arguments. Summarizes values against a specific record’s key. You need to pass additional argument for summarization:

* key - the record’s key name which values should be summarized. Only numeric fields (range_keyN) can be summarized.
nextYou can use the pagination when the number of groups within the returned aggregation exceeds 100 groups. In this case, the REST API will return the next value in the first response. You need to use this value to query the next batch of groups and update this value with the value from the prior response every time you query a subsequent batch of groups.

cURL request

curl --request POST \
--url 'https://{restApiURLAddress}/api/records/aggregate' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"next": "ZGluZyBkb25nIGNoaW5nIGNob25n",
"metrics": {
"total_revenue": {
"func": "sum",
"key": "range_key3"
},
"total_tax": {
"func": "sum",
"key": "range_key4"
},
"transaction_count": {
"func": "count"
}
},
"filter": {
"range_key2": {"$gte":1000, "$lte":4000},
"key4": "Order with Shipping"
},
"options": {
"limit": 100,
"offset": 0
}
}'

//URL EXAMPLE
https://se-restapi-mt-01.incountry.io/api/records/aggregate

When you query the next batch of groups within the aggregation, you can pass only the next value within the request:

curl --request POST \
--url 'https://{restApiURLAddress}/api/records/aggregate' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"next": "ZGluZyBkb25nIGNoaW5nIGNob25n",
}'

//URL EXAMPLE
https://se-restapi-mt-01.incountry.io/api/records/aggregate

Responses

STATUS 200 - JSON This response returns the results of aggregation and summarization.

Example:

{
"data": {
"additionalProp1": {
"group": {
"keys": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
}
},
"metrics": {
"additionalProp1": 0,
"additionalProp2": 0,
"additionalProp3": 0
}
},
"additionalProp2": {
"group": {
"keys": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
}
},
"metrics": {
"additionalProp1": 0,
"additionalProp2": 0,
"additionalProp3": 0
}
},
"additionalProp3": {
"group": {
"keys": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
}
},
"metrics": {
"additionalProp1": 0,
"additionalProp2": 0,
"additionalProp3": 0
}
}
},
"meta": {
"next": "string"
},
"errors": [
"string"
]
}

STATUS 400 - This response is returned when invalid filters or aggregation parameters are used.

STATUS 401 - This response is returned when the request is unauthorized.

STATUS 5xx- Server error.

Deleting a record

DELETE /api/records/{country}/{key}

Request parameters

ParametersTypeValueDescription
countryISO country code (lowercase)sgCountry where the record is stored
keystring/arrayk1234Unique primary key (record_key) for record identification

cURL request

curl --request DELETE \
--url 'https://{restApiURLAddress}/api/records/{country}/{key}' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \

//URL EXAMPLE
https://se-restapi-mt-01.incountry.io/api/records/se/d1c2e12cfeababc8b95daf6902e210b1

Responses

STATUS 204 - plain This response is returned when the record has been successfully deleted.

STATUS 401 - This response is returned when the request is unauthorized.

STATUS 404 - plain This response is returned when the record is not found.

STATUS 5** - Server error.

Deleting multiple records

POST /api/records/batch/delete

Request parameters

ParametersTypeExampleDescription
filterobjectSee the example.Specify the criteria for deletion within the filter object. Currently only deletion by record_key is supported.
> record_keyarraySee the example.Array of records that are subject to removal.

Please see the example of the request structure.

{
"filter": {
"record_key": [
"string"
]
}
}

cURL request

curl --request POST \
--url 'https://{restApiURLAddress}/api/records/batch/delete' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"filter": {
"record_key": [
"d1c2e12cfeababc8b95daf6902e210b1",
"d1cg88ecfeababc8b95daf690g4210b1",
"f7fg88ecfeababc8b95daf690gf8s7dd"
]
}

//URL EXAMPLE
https://se-restapi-mt-01.incountry.io/api/records/batch/delete

Responses

STATUS 204 - plain This response is returned when records have been successfully deleted.

STATUS 400 - application/json Bad request when it has not passed validation. The error details will be in the response.

STATUS 401 - This response is returned when the request is unauthorized.

STATUS 5** - Server error.

Management of attachments

You can manage attachments stored on the InCountry platform, as follows:

Available attachment fields

FieldTypeSpecifics
file_idstringUnique identifier of an attachment.
filenamestringName of an attachment.
hashstringHash of an attachment.
mime_typestringMIME type of an attachment.
sizestringSize of an attachment in bytes.
created_atstring (date-time)Timestamp when an attachment was uploaded to the InCountry platform.
updated_atstring (date-time)Timestamp when an attachment was updated on the InCountry platform.
download_linkstringLink to download an attachment from the InCountry platform.

Uploading attachments

POST ​/api​/records​/{country}​/{key}​/files

Request parameters

All the request parameters are required.

ParametersTypeValueDescription
countrystring (ISO country code (lowercase))sgCountry which a new attachment is uploaded to.
keystringatt1234A record key of the record which the attachment is associated with.
filestring@company_logo.png;type=image/pngA name of the attachment for upload.

The request body should be a binary string of the file you are uploading.

cURL request

curl --request POST \
--url 'https://{restApiURLAddress}/api/records/{country}/{id}/files' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \
--header 'Content-Type: multipart/form-data; boundary=---011000010111000001101001' \
--form 'file=@"{file local path}"'

//URL EXAMPLE
https://se-restapi-mt-01.incountry.io/api/records/se/d1c2e12cfeababc8b95daf6902e210b1/files

//LOCAL PATH TO FILE EXAMPLE
--form 'file=@"/Users/John/Projects/files/index.html"'

Responses

STATUS 201 - plain This response is returned when the attachment has been successfully added.

Example:

{
"file_id": "5416a334-6ce6-4e3b-9a0d-464cb417c094",
"filename": "index.html",
"hash": "78701b482fc9738e26f32254bbe7d71990f5025a9b728046a280a3822cdf5cad",
"mime_type": "application/x-sh",
"size": 279,
"created_at": "2021-03-26T11:36:44.000Z",
"updated_at": "2021-03-26T11:36:44.000Z",
"download_link": "https://se-mt-01.incountry.io/v2/storage/records/se/310459560d9e757d6e51be45a5aad862fbb81c52d72a026e75d21366ac223a40/attachments/5416a334-6ce6-4e3b-9a0d-464cb417c094"
}

STATUS 401 - This response is returned when the request is unauthorized.

STATUS 5** - Server error.

Downloading attachments

GET ​/api/records/{country}/{key}/files/{fileId}

Request parameters

All the request parameters are required.

ParametersTypeValueDescription
countrystring (ISO country code (lowercase))sgCountry where the attachment is stored.
keystringatt1234A record key of the record which the attachment is associated with.
fileIdstringThe file identifier of the attachment stored on the InCountry platform.

cURL request

curl --request GET \
--url 'https://{restApiURLAddress}/api/records/{country}/{id}/files/{file id}' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \

//URL EXAMPLE
https://se-restapi-mt-01.incountry.io/api/records/se/d1c2e12cfeababc8b95daf6902e210b1/files/d4f0a504-82a6-40b7-b153-1ec81d2f5ae0

Responses

STATUS 200 - plain This response is returned when the attachment has been provided for download.

Example:

{
"file_id": "string",
"filename": "string",
"hash": "string",
"mime_type": "string",
"size": 0,
"created_at": "2021-02-10T07:29:32.611Z",
"updated_at": "2021-02-10T07:29:32.611Z",
"download_link": "string"
}

STATUS 401 - This response is returned when the request is unauthorized.

STATUS 5** - Server error.

Deleting attachments

DELETE ​/api/records/{country}/{key}/files/{fileId}

Request parameters

All the request parameters are required.

ParametersTypeValueDescription
countrystring (ISO country code (lowercase))sgCountry where the attachment is stored.
keystringatt1234A record key of the record which the attachment is associated with.
fileIdstringThe file identifier of the attachment stored on the InCountry platform.

cURL request

curl --request DELETE \
--url 'https://{restApiURLAddress}/api/records/{country}/{id}/files/{fileId}' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \

// URL EXAMPLE
https://se-restapi-mt-01.incountry.io/api/records/se/d1c2e12cfeababc8b95daf6902e210b1/files/d4f0a504-82a6-40b7-b153-1ec81d2f5ae0

Responses

STATUS 204 - plain This response is returned when the attachment has been successfully deleted.

STATUS 401 - This response is returned when the request is unauthorized.

STATUS 5** - Server error.

Integrations

The Rest API can be extended with add-ons that can are called Integrations. Currently, Salesforce , ServiceNow and Serverless integrations are supported.

Salesforce

The Salesforce integration enables specific features of the InCountry REST API to work with Salesforce.

ServiceNow

The ServiceNow integration enables specific features of the InCountry REST API to work with ServiceNow.