EverReal
  • Introduction
  • Authentication
    • API ClientID and ClientSecret
    • Authentication limitations
  • Rate limiting
  • Helpers
    • Errors
    • Pagination
    • Formatting
  • How to guide
    • EverReal Data Import Process
      • Connect an Integration
      • Import Mappers
      • Ideal CSV Structure
      • Debug Imports
      • FAQ
    • Data import via GraphQL
  • Endpoints
    • Account users / members
    • Owners
      • Owners Query
      • Owners Mutation
    • Property Groups
      • Property Groups Query
      • Property Group Mutation
    • Properties
      • Properties Query
      • Properties Mutation
    • Units
      • Units Query
      • Units Mutation
    • Listing
      • Listing Query
      • Listing Mutation
    • Candidates
      • Candidates Query
      • Candidate Mutation
    • Messages
    • Contact Activites
    • Tenants
      • Tenants Query
      • Tenant Mutation
    • Contract
      • Contract Query
      • Contract Mutation
    • Contacts
      • Contact Mutation
      • Contact Query
    • Document management
      • Document management
      • Simple file upload
    • Tasks
      • Tasks Query
    • Protocols
      • Protocol Query
  • Webhooks
    • Owner Events
      • OWNER_CREATED
      • OWNER_UPDATED
      • OWNER_DELETED
    • Property Events
      • PROPERTY_CREATED
      • PROPERTY_UPDATED
      • PROPERTY_DELETED
    • Unit Events
      • UNIT_CREATED
      • UNIT_UPDATED
      • UNIT_DELETED
    • Listing Events
      • LISTING_ACTIVATED
      • LISTING_ARCHIVED
      • LISTING_UPDATED
      • LISTING_DEACTIVATED
      • LISTING_CREATED
      • LISTING_PUBLISHED_TO_CHANNEL
      • LISTING_UNPUBLISHED_FROM_CHANNEL
    • Candidates Events
      • CANDIDATE_PARSED
      • LISTING_CANDIDATE_APPLIED
    • Listing Contracting Events
      • LISTING_CONTRACT_FLOW_SIGNED
      • LISTING_CONTRACT_FLOW_PARTIALLY_SIGNED
      • LISTING_CONTRACT_FLOW_WITHDRAWN
      • LISTING_CONTRACT_FLOW_STARTED
    • Listing Scheduling Events
      • LISTING_CANDIDATE_SCHEDULE_TIMESLOT_BOOKING_REMOVED_CANDIDATE
      • LISTING_CANDIDATE_SCHEDULE_TIMESLOT_BOOKING_REMOVED_ADMIN
      • LISTING_CANDIDATE_SCHEDULE_TIMESLOT_BOOKED_CANDIDATE
      • LISTING_CANDIDATE_SCHEDULE_TIMESLOT_BOOKED_ADMIN
      • LISTING_CANDIDATE_SCHEDULE_NEW_TIMESLOTS_REQUESTED
      • LISTING_CANDIDATE_SCHEDULE_INVITED_VIEWING
    • Protocol Events
      • PROTOCOL_COMPLETED
  • Change log
    • Releases
      • Introducing Mappers
      • Enhancements for GraphQL
      • Enhancements for Querying
      • Enhancements for Webhooks
    • Upcoming
      • Introduced Querying Protocol in GraphQL
Powered by GitBook
On this page
  • Requirements
  • Authentication
  • Refresh token in case it expires
  • User information

Was this helpful?

Authentication

EverReal implements OAuth 2.1 authentication standard on top of its APIs. Before you can use our SSO API, everreal has to generate a client_id and client_secret for the SSO.

PreviousIntroductionNextAPI ClientID and ClientSecret

Last updated 1 year ago

Was this helpful?

Requirements

EverReal APIs supports jwt tokens using according to . This allows us to protect our information and make sure, who is requesting has correct authorization to execute the operation.

OAuth 2.0 Password Grant

Important! You should use the password grant only in server-to-server communication, where you completely trust the client.

This allows you to use the username and password to get the refresh_token. After refresh_token is obtain, username and password is not needed.

Authentication

POST https://{custom_subdomain}.everreal.co/accounts/oauth/token

Headers

Name
Type
Description

Content-Type

string

application/json

Request Body

Name
Type
Description

Payload body

object

{ "username": "john.doe@everreal.co", "password": "Password", "client_id": "<Client_iD>", "client_secret": "<Client Secret>", "scope": "offline_access *", "grant_type": "password" }

{
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjYTdhZDI2MC1mNmE3LTQ1OWEtOWNjYy1kNTMzMzNjY2M1Y2EiLCJzdWIiOiI3NmFmY2FiMC02NTJiLTQ1NDctODAxYi03YzcwMWMwOTdiODEiLCJleHAiOjE2Mjg1OTYyNTYsImlhdCI6MTYyODU5MjY1Nn0.nnBmf0r7oTsqDYxwkA9seO-aZGhLY3z-ZodFn2NSa9gPOxCCtXvACj7UNIifd03KbqLDiJcpqj5anUzyKpXY0taXRCPMVHB78iVYDyKR8rZqNZ7PP8XSXvxxLaZPfTiqYG01pzCgaDWHwgpUsBoFRJDr2rPt1ShD6Pe-efcZIQfS81jGUAw4dYAwnot6zNC6uNY8OkihEUEwnsVI1mCfjvmrWL6cHmL-YSko-gPUGAjF1ulSJZ68CcMTrsC2tXnWLAMyiJMu9_VWoLXUgQJH2FzISeJkyPCJbnzDlMmAYfe8Kq0z8QL_l2q_cs2aOAvre-jJpyri-dsP-6hR2ODL4g",
    "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2ZWU5YzFhNi1hMWM5LTQwOWQtYjJjOS03NjdlZGRlMzAwNDQiLCJzdWIiOiI3NmFmY2FiMC02NTJiLTQ1NDctODAxYi03YzcwMWMwOTdiODEiLCJleHAiOjE2MzExODQ2NTYsImlhdCI6MTYyODU5MjY1Nn0.IcdmncHIE3PTxix5QS5bZAm3JsPDprRqyEU6pEk09mViV-V9F8EWlYofDuQglfB5vNe_oBzZWmu3wdxGm7hO-9Z_sveI6OEBy-mv_-bHarIRytToH7zjSkl4BO_l-s48hwxGVYyQLtFX1G9vU-ykJ4Bwd4M6V1Z-0gwW65MCFn6CXgAz8lXgDLoLorwoxGjZVMKFmjNQcNLLdcLXDNXXYdU6d2bjJQLz6hzixbqhUFYbR6hZUbEJ6cBZsKWZjsvDydtJ9froWR3d4C4tbYkirmSGvZHjvtwVrjKnoHtAd0MQ8UVTKxrH7jTcATrCmWDaxyW2XFcd7HtuI3_TdQH8aw",
    "expires_in": 3600,
    "token_type": "Bearer"
}
{
    "error": "invalid_grant",
    "error_description": "heimdall.validation.user.does.not.exist"
}

  • Make sure to store the refresh_token securely.

  • Currently the refresh_token has an expiration between 4 weeks and 2 years, it is configurable

    by EverReal for each customer. After it expires you need to re-authenticate with username and

    password

  • The access_token expires by default every hour, but also can be configurable by EverReal to

    have another expiration time (it is described by the expires_in property). Use the

    refresh_token to generate a new one if you get an unauthorized response

Bellow you can see some examples to get token correctly.

curl --location --request POST 'https://{custom_subdomain}.everreal.co/accounts/oauth/token' \
--header 'Content-Type: application/json' \
--header 'Cookie: accept-language=de-DE' \
--data-raw '{ 
"username": "john.doe@everreal.co", 
"password": "Password", 
"client_id": "<Client_iD>", 
"client_secret": "<Client Secret>", 
"scope": "offline_access *", 
"grant_type": "password" 
}'
var client = new RestClient($"https://{custom_subdomain}.everreal.co/accounts/oauth/token");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Cookie", "accept-language=de-DE");
var body = @"{ 
" + "\n" +
@"""username"": ""john.doe@everreal.co"", 
" + "\n" +
@"""password"": ""Password"", 
" + "\n" +
@"""client_id"": ""<Client_iD>"", 
" + "\n" +
@"""client_secret"": ""<Client Secret>"", 
" + "\n" +
@"""scope"": ""offline_access *"", 
" + "\n" +
@"""grant_type"": ""password"" 
" + "\n" +
@"}";
request.AddParameter("application/json", body,  ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
var axios = require('axios');
var data = JSON.stringify({
  "username": "john.doe@everreal.co",
  "password": "Password",
  "client_id": "<Client_iD>",
  "client_secret": "<Client Secret>",
  "scope": "offline_access *",
  "grant_type": "password"
});

var config = {
  method: 'post',
  url: `https://{custom_subdomain}.everreal.co/accounts/oauth/token`,
  headers: { 
    'Content-Type': 'application/json', 
    'Cookie': 'accept-language=de-DE'
  },
  data : data
};

axios(config)
.then(function (response) {
  console.log(JSON.stringify(response.data));
})
.catch(function (error) {
  console.log(error);
});
import requests
import json

url = "https://{custom_subdomain}.everreal.co/accounts/oauth/token"

payload = json.dumps({
  "username": "john.doe@everreal.co",
  "password": "Password",
  "client_id": "<Client_iD>",
  "client_secret": "<Client Secret>",
  "scope": "offline_access *",
  "grant_type": "password"
})
headers = {
  'Content-Type': 'application/json',
  'Cookie': 'accept-language=de-DE'
}

response = requests.post(url, headers=headers, data=payload)

print(response.text)

client_id and client_secret are parameter provided by EverReal

Oauth2.0 Authorization Code Flow

Important! Use the Authorization Code Flow in not trusted environments, like Web or Mobile app clients. Below are the necessary endpoints for the Authorization Code Flow.

authorizationUri="https://${subdomain}.everreal.co/accounts/dialog/authorize"
accessTokenUri="https://${subdomain}.everreal.co/accounts/oauth/token"
tokenInfoUri="https://${subdomain}.everreal.co/accounts/api/tokeninfo?access_token={token}"
revokeTokenUri="https://${subdomain}.everreal.co/accounts/api/tokenrevoke?token={token}"
userInfoUri="https://${subdomain}.everreal.co/accounts/api/userinfo"
{
  id: "everreal",
  name: "EverReal",
  type: "oauth",
  version: "2.0",
  scope: "offline_access *",
  params: { grant_type: "authorization_code" },
  accessTokenUrl: `https://${subdomain}.everreal.co/accounts/oauth/token`,
  requestTokenUrl: `https://${subdomain}.everreal.co/accounts/oauth/token`,
  authorizationUrl: `https://${subdomain}.everreal.co/accounts/dialog/authorize`,
  profileUrl: `https://${subdomain}.everreal.co/accounts/api/userinfo`,
  async profile(profile, tokens) {
    return {
       ...profile
    }
  },
  clientId: "provided by everreal",
  clientSecret: "provided by everreal"
}

Refresh access_token API endpoint

Refresh token in case it expires

POST https://{custom_subdomain}.everreal.co/accounts/oauth/token

Refresh the access_token in case it expires

Headers

Name
Type
Description

Content-Type

string

application/json

Request Body

Name
Type
Description

string

{ "grant_type":"refresh_token", "client_id": "{secret}", "client_secret": "{secret}", "refresh_token":"{refresh_token}" }

{
"access_token": "NEW TOKEN",
"expires_in": "3600" 
}

Use the access_token to authenticate to any protected endpoint by passing it to the “Authorization” header like this: “Authorization: Bearer MY_ACCESS_TOKEN”

User information

GET https://{custom_subdomain}.everreal.co/accounts/api/users/me

Based on Bearer token provided in header request, it will retrieve user information and all information about it.

Headers

Name
Type
Description

Content-Type

string

application/json

Authorization

string

Bearer token

{
    "id": "76dccab0-652e-4543-802c-7c701c098ad3",
    "email": "john.doe@ovooovo.com",
    "isActive": true,
    "firstName": null,
    "lastName": null,
    "profilePhoto": null,
    "profileData": {
        "language": "en-US"
    },
    "isTenant": false,
    "createdAt": "2021-07-19T14:21:50.215Z",
    "updatedAt": "2021-07-19T14:21:50.215Z",
    "areTermsAccepted": true,
    "companies": [
        {
            "id": "76dccab0-652e-4543-802c-7c701c0b3bb3",
            "name": "automation-reporting-qa",
            "isDefault": true
        }
    ],
    "currentCompany": {
        "id": "76dccab0-652e-4543-802c-7c701c0b3bb3",
        "name": "automation-reporting-qa",
        "partner": {
            "id": "76dccab0-652e-4543-802c-7c701c046579",
            "name": "test-documentation",
            "subdomain": "test-documentation"
        },
        "isDefault": true
    },
    "tokenInfo": {
        "audience": "76dccab0-652e-4543-802c-7c701c0a68f6",
        "scope": [
            "offline_access",
            "company_contracting_edit_contract",
            "message_templates_all",
            "company_portfolio_all",
            "company_user",
            "email_templates_all"
        ],
        "user_id": "76dccab0-652e-4543-802c-7c701c097b81",
        "expires_in": 3571
    }
}

A basic next.js example can be over our github page :

Read more here:

Bearer token
RFC-7519
https://github.com/EverRealGMBH/everreal-nextjs-nextauth-oauth2-example
https://next-auth.js.org/v3/configuration/providers#using-a-custom-provider