Skip to main content

Getting Started with REST API

Welcome to 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 Data Residency-as-a-Service (DRaaS), along with the expected HTTP response codes and sample requests.

InCountry REST API is a set of RESTful methods that allow you to query regulated data from the InCountry Data Residency-as-a-Service (DRaaS). It simplifies data communication and lets you quickly build applications with data localization capabilities.

The data flow diagram is shown below:

REST API Diagram

You can make CRUD requests through REST API to access regulated data stored on the InCountry platform.

note

Executing calls from the frontend (browser) requires an additional layer of authorization checks to ensure that the current user is allowed to perform the requested operation on the specified resources. For more details, please 📃 refer to the documentation

Prerequisites

  1. Create a new REST API service.

  2. Create data Schema.

    For this guide, assume a schema named Users is defined as follows:

       first_name: String
    last_name: String
    passport: String
    salary: Integer
  3. Copy details of the REST API integration, as follows:

    1. Environment ID

    2. Client ID

    3. Client Secret

    4. REST API address

      REST API integration

Creating an Access Token

To obtain an oAuth token, you should send a request to the authorization server with the credentials received on InCountry Portal.

Firstly, you need to determine AUTH_ENDPOINT for your country. Under the spoiler you can find available countries and corresponding auth servers.

Countries and auth endpoints

The following documentation lists the country codes supported by the InCountry platform.

This data was current as of January 2024.

Americas

note

Please use the following authorization endpoint when writing regulated data to the countries of this region: https://auth-emea.incountry.com/oauth2/token/

Country CodeCountry
BRBrazil
CACanada
USUnited States

Asia & Asia-Pacific

note

Please use the following authorization endpoint when writing regulated data to the countries of this region: https://auth-apac.incountry.com/oauth2/token/

Country CodeCountry
AUAustralia
CNChina
INIndia
IDIndonesia
JPJapan
SGSingapore
KRSouth Korea

Europe

note

Please use the following authorization endpoint when writing regulated data to the countries of this region: https://auth-emea.incountry.com/oauth2/token/

Country CodeCountry
FRFrance
DEGermany
IEIreland
NLNetherlands
RURussia
GBUnited Kingdom

Middle East & Africa

note

Please use the following authorization endpoint when writing regulated data to the countries of this region: https://auth-emea.incountry.com/oauth2/token/

Country CodeCountry
AEUnited Arab Emirates
SASaudi Arabia

Updates & Accuracy

note

Please note that this may not be an exhaustive list. For more information, please contact us at sales@incountry.com

The CURL request template is the following:

curl '{AUTH_ENDPOINT}' \
--user '{client_id}:{client_secret}' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'User-Agent: Client-name' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'audience={restapi_url} {storage_url}' \
--data-urlencode 'scope={environment_id}'

You received client_id, client_secret, environment_id and restapi_url on the Step 3 of Prerequisites. To get storage_url, remove "-restapi" substring from the restapi_url. For example, if restapi_url=https://id-restapi-mt-01.api.incountry.io then storage_url=https://id-mt-01.api.incountry.io.

note

The User-Agent header is mandatory. You can set it to any value you want or leave it as the default if your HTTP client has one.

The response is defined as follows:

{
"access_token": <token>,
"expires_in": 300,
"scope": <environment_id>,
"token_type": "bearer"
}

Use access_token as a Bearer auth token for all subsequent requests to RestAPI.

Creating a New Record

Let's say we want to add a new User. To create a record send a POST request to /api/{modelName} path.

Example:

curl 'https://in-restapi-mt-01.api.incountry.io/api/users' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ory_at_05MJ4MHOkRhW0A0wduM8Ehr_cRsk5acakP6u4dn2rFo.23THKavIs_PHKMR8W-AxaPmEq10ymWQC_fttHio_FlE' \
--data '{
"record_key": "user1_primary_key",
"first_name": "John",
"last_name": "Smith",
"passport": "25534512",
"salary": 10000
}'
tip

Pay attention that every record must have a unique record_key across the environment (within the same environment_id). It serves as a primary key, enabling you to access, modify, or delete your record.

Creating Multiple Records

There is a way to create multiple record in one request. Now we're adding 2 more users to InCountry Storage.

Example:

curl 'https://in-restapi-mt-01.api.incountry.io/api/users/batch' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ory_at_05MJ4MHOkRhW0A0wduM8Ehr_cRsk5acakP6u4dn2rFo.23THKavIs_PHKMR8W-AxaPmEq10ymWQC_fttHio_FlE' \
--data '{
"records": [
{
"record_key": "user2_primary_key",
"first_name": "Jake",
"last_name": "Bruce",
"passport": "7466732",
"salary": 15000
},
{
"record_key": "user3_primary_key",
"first_name": "Mike",
"last_name": "Johnson",
"passport": "25544444",
"salary": 12000
}
]
}'
note

There is a limit for the number of records in one batch, which is set to 1000.

Searching for Records

Now that we have some records available in the Storage, let's execute a search to find some of them. There is a find endpoint that allows you to specify search criteria. Let's say we want to retrieve users with the salary field set in the range of 11000 to 30000.

curl 'https://in-restapi-mt-01.api.incountry.io/api/users/find' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ory_at_05MJ4MHOkRhW0A0wduM8Ehr_cRsk5acakP6u4dn2rFo.23THKavIs_PHKMR8W-AxaPmEq10ymWQC_fttHio_FlE' \
--data '{
"filter": {
"salary": {"$gte":11000, "$lte":30000}
},
"options": {
"limit": 10,
"offset": 0
}
}'

This will give us two users matching the criteria. The response will look as follows:

{
"data": [
{
"record_key": "user2_primary_key",
"first_name": "Jake",
"last_name": "Bruce",
"passport": "7466732",
"salary": 15000,
"attachments": [],
"created_at": "2021-03-26T11:57:45.000Z",
"updated_at": "2021-03-26T11:57:45.000Z"
},
{
"record_key": "user3_primary_key",
"first_name": "Mike",
"last_name": "Johnson",
"passport": "25544444",
"salary": 12000,
"attachments": [],
"created_at": "2021-03-26T11:57:45.000Z",
"updated_at": "2021-03-26T11:57:45.000Z"
}
],
"meta": {
"count": 2,
"limit": 10,
"offset": 0,
"total": 2
}
}

You can find more information about using find endpoint in the reference.

Deleting a Specific Record

Now, let's delete a record. To do so, we need to use the record_key of the record we want to delete. For example, let's delete a record with the key user1_primary_key. Example:

curl --request DELETE \
--url 'https://in-restapi-mt-01.api.incountry.io/api/users/in/user1_primary_key' \
--header 'Authorization: Bearer ory_at_05MJ4MHOkRhW0A0wduM8Ehr_cRsk5acakP6u4dn2rFo.23THKavIs_PHKMR8W-AxaPmEq10ymWQC_fttHio_FlE'

This endpoint doesn't respond with a body.

Attaching a File

It is possible to attach a file to a record.

note

Keep in mind that files cannot exist separately and should always be attached to some record. Deleting a record will result in the deletion of all the files attached to it.

Example:

curl --request POST \
--url 'https://in-restapi-mt-01.api.incountry.io/api/users/in/user2_primary_key/files' \
--header 'Authorization: Bearer ory_at_05MJ4MHOkRhW0A0wduM8Ehr_cRsk5acakP6u4dn2rFo.23THKavIs_PHKMR8W-AxaPmEq10ymWQC_fttHio_FlE' \
--header 'Content-Type: multipart/form-data; boundary=---011000010111000001101001' \
--header 'x-filename: expenses.pdf' \
--form 'file=@"/documents/expenses.pdf'

In this example we attached a file expenses.pdf to a record with record_key="user2_primary_key". In the response you will get information about attachment:

{
"file_id": "5416a334-6ce6-4e3b-9a0d-464cb417c094",
"filename": "expenses.pdf",
"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://in-mt-01.incountry.io/v2/storage/records/in/310459560d9e757d6e51be45a5aad862fbb81c52d72a026e75d21366ac223a40/attachments/5416a334-6ce6-4e3b-9a0d-464cb417c094"
}

The file_id field is the attachment's unique identifier and is used to access and modify the attachment.

Downloading an Attached File

curl --request GET \
--url 'https://{restApiUrl}/api/{modelName}/{country}/{record_key}/files/{file_id}' \
--header 'Authorization: Bearer {ACCESS_TOKEN}'

In our case, the request will be the following:

curl --request GET \
--url 'https://in-restapi-mt-01.api.incountry.io/api/users/in/user2_primary_key/files/5416a334-6ce6-4e3b-9a0d-464cb417c094' \
--header 'Authorization: Bearer ory_at_05MJ4MHOkRhW0A0wduM8Ehr_cRsk5acakP6u4dn2rFo.23THKavIs_PHKMR8W-AxaPmEq10ymWQC_fttHio_FlE'

Deleting an Attached File

To delete an attachment, execute a DELETE request and specify record_key and file_id.

The request template is as follows:

curl --request DELETE \
--url 'https://{restApiURLAddress}/api/{modelName}/{country}/{id}/files/{file_id}' \
--header 'Authorization: Bearer {ACCESS_TOKEN}' \

In our case, the request will be the following:

curl --request DELETE \
--url 'https://in-restapi-mt-01.api.incountry.io/api/users/in/user2_primary_key/files/5416a334-6ce6-4e3b-9a0d-464cb417c094' \
--header 'Authorization: Bearer ory_at_05MJ4MHOkRhW0A0wduM8Ehr_cRsk5acakP6u4dn2rFo.23THKavIs_PHKMR8W-AxaPmEq10ymWQC_fttHio_FlE'