SDK integration for registration
DataDome Account Protect detects account takeover threats and protects you against them
Account Protect can be integrated into your backend through SDK packages available on multiple platforms.
Prerequisites for Account ProtectAccount Protect is separate from Bot Protect and is not available on your account by default.
Please contact your account manager to enable it.This service requires a dedicated API key, which will be available on your dashboard once it is enabled.
Main Concepts
When a user attempts to register on your website, the fraud protection SDK sends data to DataDome's Account protect API:
- The Account Protect API will respond with a recommendation (to either allow or deny the login).
- A recommendation means that your application will still make the final decision. You can either invalidate the account or mark it as "downgraded"

Overview of the implementation flow for a registration attempt.
Installation
Upgrading an existing integrationThe Go, Java, and .NET SDKs are now generated from the Account Protect OpenAPI specification, and their latest major versions contain breaking changes. Follow the migration guides to upgrade your integration.
The Account Protect SDK is distributed on multiple platforms:
- Maven package for Java 11+ and Spring Boot 2.x
- Maven package for Java 17+ and Spring Boot 3.x - compatible with Scala 2.12+
- Npm package for Node.js 14+
- NuGet package for .NET 6
- Packagist package for Symfony PHP (8.1+) applications
- Packagist package for Laravel PHP (8.1+) applications
- Pypi package for Python 3.8+
- Ruby gem for Ruby 3.2+
- Go package for Go 1.18+
You can use one of the commands below to install the relevant package for your application:
npm i @datadome/fraud-sdk-nodedotnet add package DataDome.AspNetCore.Fraud.SDK<!-- insert in the pom.xml file of the project -->
<dependency>
<groupId>co.datadome.fraud</groupId>
<artifactId>fraud-sdk-java</artifactId>
<version>3.0.0</version>
</dependency>libraryDependencies += "co.datadome.fraud" % "fraud-sdk-java" % "3.0.0"pip install datadome-fraud-sdk-pythoncomposer require datadome/fraud-sdk-symfony# 1. add `datadome/fraud-sdk-laravel` to your project
composer require datadome/fraud-sdk-laravel
# 2. Generate an autoloader
composer dump-autoload
# 3. Edit `config/app.php` to add `DataDomeServiceProvider`
# config/app.php
use DataDome\FraudSdkLaravel\Providers\DataDomeServiceProvider;
[...]
'providers' => ServiceProvider::defaultProviders()->merge([
[...]
DataDomeServiceProvider::class
# 4. publish `datadome.php` in the `config` folder
php artisan vendor:publishgem install datadome_fraud_sdk_rubygo get github.com/datadome/fraud-sdk-go-package/v2Usage
Using the Account Protect SDK requires changes in your application to send signals regarding the registration and handle the recommendations provided by DataDome's Account Protect API.
Example for a Registration event
const datadomeClient = new DataDome("FraudAPIKey");
app.post('/register', async function (req, res) {
const emailAccount = req.body.email;
const session = { id: 'sessionId', createdAt: new Date() };
const userAddress = {
name: 'HQ',
line1: '22 rue de la Michodiere',
line2: '2nd floor',
city: 'Paris',
countryCode: 'FR',
country: 'France',
regionCode: '75',
zipCode: '75002'
};
const user = {
id: 'userId',
title: 'mrs',
firstName: 'Data',
lastName: 'Dome',
createdAt: new Date(),
phone: '+33978787878',
email: emailAccount,
address: userAddress,
displayName: 'DataDome 🤖',
description: 'Some Description',
externalUrls: [
'https://example.org/external1',
'https://example.org/external2',
'https://example.org/external3',
],
pictureUrls: [
'https://example.org/image1.png',
'https://example.org/image2.png',
'https://example.org/image3.png',
],
};
const authentication: Authentication = {
socialProvider: 'google',
type: 'social',
mode: 'password',
};
const customFields: CustomField[] = [{
name: "customField",
value: "customValue",
}];
const registrationEvent = new RegistrationEvent({
account: emailAccount,
authentication,
session,
user,
customFields,
});
const datadomeResponse = await datadomeClient.validate(req, registrationEvent);
if (datadomeResponse?.action == ResponseAction.ALLOW) {
// Process registration of the user
res.status(200).send(`Successfully created user ${req.body.email}`);
} else {
res.status(401).send(`Access denied [by DD] ! ${datadomeResponse?.reasons[0]}`);
}
});using DataDome.AspNetCore.Fraud.SDK;
using DataDome.AspNetCore.Fraud.SDK.Api;
using DataDome.AspNetCore.Fraud.SDK.Model;
var appBuilder = WebApplication.CreateBuilder(args);
appBuilder.Services.AddSingleton(_ => Client.Builder("your-api-key").Build());
var app = appBuilder.Build();
app.MapPost("/registration", RegistrationHandler);
app.Run();
static IResult RegistrationHandler(HttpContext ctx, Client client)
{
var email = ctx.Request.Form["email"].ToString();
var userAddress = new UserAllOfAddress
{
City = "Paris",
CountryCode = "FR",
Line1 = "22 rue de la Michodiere",
Line2 = "2nd floor",
Name = "HQ",
RegionCode = "75",
ZipCode = "75002",
};
var authentication = new RegistrationPayloadAllOfAuthentication
{
Mode = AuthenticationMode.Password,
SocialProvider = AuthenticationSocialProvider.Google,
Type = AuthenticationType.Social,
};
var user = new RegistrationPayloadAllOfUser
{
Id = "fake_user_id",
Address = userAddress,
CreatedAt = DateTime.UtcNow,
Email = email,
FirstName = "Data",
LastName = "Dome",
Phone = "+33978787878",
Title = UserTitle.Mrs,
DisplayName = "DataDome",
Description = "Some Description",
ExternalUrls = new List<string>
{
"https://example.org/external1",
"https://example.org/external2",
"https://example.org/external3",
},
PictureUrls = new List<string>
{
"https://example.org/image1.png",
"https://example.org/image2.png",
"https://example.org/image3.png",
},
};
var session = new Session { Id = "sessionId", CreatedAt = DateTime.UtcNow };
var builder = new RegistrationPayload.Builder()
.Account(email)
.User(user)
.Authentication(authentication)
.Session(session);
var validate = new ValidateRegistration(builder).Perform(client, ctx.Request, null);
if (validate?.Action == ResponseAction.Allow)
{
return Results.Ok();
}
else
{
// Business Logic here
return Results.Problem("failed", statusCode: 403);
}
}package example;
import co.datadome.fraud.Client;
import co.datadome.fraud.ApiException;
import co.datadome.fraud.api.*;
import co.datadome.fraud.model.*;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.time.Instant;
import java.util.List;
import java.util.logging.Logger;
@SpringBootApplication
@RestController
public class ExampleApplication {
private static final Logger logger = Logger.getLogger(ExampleApplication.class.getName());
@Bean
public Client fraudClient() {
return Client.builder("your-api-key").build();
}
private final Client client;
public ExampleApplication(Client client) {
this.client = client;
}
public static void main(String[] args) {
SpringApplication.run(ExampleApplication.class, args);
}
@PostMapping("/registration")
public ResponseEntity<String> registrationHandler(
@RequestParam String email,
HttpServletRequest request) {
UserAllOfAddress userAddress = new UserAllOfAddress();
userAddress.setName("HQ");
userAddress.setLine1("22 rue de la Michodiere");
userAddress.setLine2("2nd floor");
userAddress.setCity("Paris");
userAddress.setCountryCode("FR");
userAddress.setRegionCode("75");
userAddress.setZipCode("75002");
RegistrationPayloadAllOfAuthentication authentication = new RegistrationPayloadAllOfAuthentication();
authentication.setMode(Authentication.Mode.PASSWORD);
authentication.setSocialProvider(Authentication.SocialProvider.GOOGLE);
authentication.setType(Authentication.Type.SOCIAL);
RegistrationPayloadAllOfUser user = new RegistrationPayloadAllOfUser();
user.setId("fake_user_id");
user.setAddress(userAddress);
user.setCreatedAt(Instant.now().toString());
user.setEmail(email);
user.setFirstName("Data");
user.setLastName("Dome");
user.setPhone("+33978787878");
user.setTitle(UserTitle.MRS);
user.setDisplayName("DataDome");
user.setDescription("Some Description");
user.setExternalUrls(List.of(
"https://example.org/external1",
"https://example.org/external2",
"https://example.org/external3"
));
user.setPictureUrls(List.of(
"https://example.org/image1.png",
"https://example.org/image2.png",
"https://example.org/image3.png"
));
Session session = new Session();
session.setId("sessionId");
session.setCreatedAt(Instant.now().toString());
RegistrationPayload.Builder builder = RegistrationPayload.builder()
.account(email)
.user(user)
.authentication(authentication)
.session(session);
try {
Response validate = new ValidateRegistration(builder).perform(client, request, null);
if (validate.getAction() == ResponseAction.ALLOW) {
return ResponseEntity.ok().build();
} else {
// Business Logic here
return ResponseEntity.status(403).body("failed");
}
} catch (ApiException e) {
logger.severe("error during validation: " + e.getMessage());
return ResponseEntity.status(403).body("failed");
}
}
}// 1. Add these imports
import co.datadome.fraud._
import co.datadome.fraud.api.request.{DataDomeMetadata, RegistrationEvent}
import co.datadome.fraud.model.{Address, User}
// 2. Declare the constant FraudApiKey with the value provided by DataDome
// 3. Initialization of DataDomeFraudService with the FraudApiKey
val dataDomeFraudService = new DataDomeFraudService(FraudApiKey)
// 4. Build data and call the service
val ddm: DataDomeMetadata = requestToDataDomeMetadata(req) // with req coming from your framework
// see below for an example implementation for Finagle
val userAddress: Address = Address.newBuilder()
.name("home")
.line1("55 Rue du Faubourg Saint-Honoré")
.line2("2nd floor")
.city("Paris")
.countryCode("FR")
.country("France")
.regionCode("75")
.zipCode("75008")
.build()
val user: User = User.newBuilder()
.id("userId")
.email(login)
.firstName("Data")
.lastName("Dome")
.phone("+33978787878")
.title("mr")
.address(userAddress)
.build()
val registrationEvent: RegistrationEvent = RegistrationEvent.newBuilder()
.user(user)
.account(login)
.build()
if (!mock.userExists(user)) {
// User does not exist - proceed with registration
/*
`validateAsync` and `collectAsync` methods return CompletableFuture<>
Note that CompletableFuture can throw Exception and must be handled in your code
*/
val dataDomeResponse: DataDomeResponse = dataDomeFraudService.validate(ddm, registrationEvent)
if (dataDomeResponse.isAllowed) {
mock.registerUser(user)
} else {
// deny
// [...]
}
} else {
// User already exists - send data for collection only
dataDomeFraudService.collect(ddm, registrationEvent)
}
// Example implementation to extract the request metadata from a Finagle request
def requestToDataDomeMetadata(req: Request): DataDomeMetadata = {
val builder = DataDomeMetadata.newBuilder()
.addr(req.remoteAddress.getHostAddress)
.method(req.method.name)
.port(req.remotePort)
.protocol(req.version.versionString)
.request(req.uri)
if (req.accept.nonEmpty) builder.accept(req.accept.mkString(", "))
// retrieve clientId
req.cookies.get("datadome").foreach(cookie => builder.clientId(cookie.value))
req.headerMap.get("accept-encoding").foreach(builder.acceptEncoding)
req.headerMap.get("accept-language").foreach(builder.acceptLanguage)
req.headerMap.get("connection").foreach(builder.connection)
req.headerMap.get("from").foreach(builder.from)
req.headerMap.get("hostname").foreach(builder.serverHostname)
req.headerMap.get("origin").foreach(builder.origin)
req.headerMap.get("x-real-ip").foreach(builder.xRealIp)
req.host.foreach(builder.host)
req.charset.foreach(builder.acceptCharset)
req.contentType.foreach(builder.contentType)
req.referer.foreach(builder.referer)
req.userAgent.foreach(builder.userAgent)
req.xForwardedFor.foreach(builder.xForwardedForIp)
builder.build()
}
// 1. Update the .env files with your preferred configuration.
DATADOME_FRAUD_API_KEY='FRAUD_API_KEY'
DATADOME_TIMEOUT=1500
DATADOME_ENDPOINT='https://account-api.datadome.co'
// 2. Add the required imports in your controller
use DataDome\FraudSdkSymfony\Config\DataDomeOptions;
use DataDome\FraudSdkSymfony\DataDome;
use DataDome\FraudSdkSymfony\Models\Address;
use DataDome\FraudSdkSymfony\Models\LoginEvent;
use DataDome\FraudSdkSymfony\Models\StatusType;
use DataDome\FraudSdkSymfony\Models\RegistrationEvent;
use DataDome\FraudSdkSymfony\Models\Session;
use DataDome\FraudSdkSymfony\Models\User;
use DataDome\FraudSdkSymfony\Models\ResponseAction;
// 3. Create a private DataDome object
$key = $_ENV['DATADOME_FRAUD_API_KEY'];
$timeout = $_ENV['DATADOME_TIMEOUT'];
$endpoint = $_ENV['DATADOME_ENDPOINT'];
$options = new DataDomeOptions($key, $timeout, $endpoint);
$dataDome = new DataDome($options);
// 4. Invoke the validate method as required
$registrationSession = new Session();
// A unique session identifier from your system
$registrationSession->id = "sessionId";
$registrationUser = new User();
// A unique customer identifier from your system. It has to be the same for all other event sent
// This property is required
$registrationUser->id = "userId";
// Provide the below properties only if available
$registrationUser->title = "mrs";
$registrationUser->firstName = "Joy";
$registrationUser->lastName = "Green";
$registrationUser->phone = "+33978787878";
$registrationUser->email = "[email protected]";
$registrationAddress = new Address();
$registrationAddress->name = "Block 17";
$registrationAddress->line1 = "Av. de l'Opéra";
$registrationAddress->line2 = "3rd floor";
$registrationAddress->city = "Paris";
$registrationAddress->countryCode = "FR";
$registrationAddress->zipCode = "75002";
$registrationUser->address = $registrationAddress;
$registrationEvent = new RegistrationEvent(
"[email protected]",
StatusType::Succeeded,
$registrationSession,
$registrationUser);
$registrationResponse = $dataDome->validate($request, $registrationEvent);
if ($registrationResponse != null && $registrationResponse->action == ResponseAction::Allow) {
// Valid registration attempt
$this->registerUser($request);
} else {
return new JsonResponse(["Registration denied; " . $registrationResponse->reasons[0] ]);
}
}from datadome_fraud_sdk_python import DataDome, ResponseAction, RegistrationEvent,
UserSession, Address, Title, User as datadomeUser
datadome_instance = DataDome("FraudAPIKey")
def signup():
account = request.form.get('email')
datadomeUserSession = UserSession(session.id)
userAddress = Address(name="Home",line1="123 Maple Street", line2="2nd floor",
city="Anytown", countrycode="FR", country="France",
regioncode="PA",zipcode="17101")
user = datadomeUser(id=account, title=Title.MR, firstname="John",lastname="Doe",
createdAt=datetime.now(),
phone="+33978787878", email=account, address=userAddress)
registrationEvent = RegistrationEvent(account, user, datadomeUserSession)
datadome_response = await datadome_instance.validate(request, registrationEvent)
if datadome_response.action == ResponseAction.ALLOW:
flash("You are allowed to register!")
db.register(user) # register user in your system
return redirect(url_for('auth.signup'))
else:
flash("You are not allowed to register, reason:" + str(datadome_response.reasons[0]))
return redirect(url_for('auth.login'))// 1. Update the .env files with your preferred configuration.
DATADOME_FRAUD_API_KEY='FRAUD_API_KEY'
DATADOME_TIMEOUT=1500
DATADOME_ENDPOINT='https://account-api.datadome.co'
// 2. Add the required imports in your controller
use DataDome\FraudSdkSymfony\Config\DataDomeOptions;
use DataDome\FraudSdkSymfony\DataDome;
use DataDome\FraudSdkSymfony\Models\Address;
use DataDome\FraudSdkSymfony\Models\StatusType;
use DataDome\FraudSdkSymfony\Models\RegistrationEvent;
use DataDome\FraudSdkSymfony\Models\Session;
use DataDome\FraudSdkSymfony\Models\User;
use DataDome\FraudSdkSymfony\Models\ResponseAction;
// 3. Invoke the validate and collect methods as required
[...]
$registrationSession = new Session();
// A unique session identifier from your system
$registrationSession->id = "sessionId";
$registrationUser = new User();
// A unique customer identifier from your system. It has to be the same for all other event sent
// This property is required
$registrationUser->id = "userId";
// Provide the below properties only if available
$registrationUser->title = "mrs";
$registrationUser->firstName = "Joy";
$registrationUser->lastName = "Green";
$registrationUser->phone = "+33978787878";
$registrationUser->email = "[email protected]";
$registrationAddress = new Address();
$registrationAddress->name = "Block 17";
$registrationAddress->line1 = "Av. de l'Opéra";
$registrationAddress->line2 = "3rd floor";
$registrationAddress->city = "Paris";
$registrationAddress->countryCode = "FR";
$registrationAddress->zipCode = "75002";
$registrationUser->address = $registrationAddress;
$registrationEvent = new RegistrationEvent(
"[email protected]",
StatusType::Succeeded,
$registrationSession,
$registrationUser);
$registrationResponse = app("DataDome")->validate($request, $registrationEvent);
if ($registrationResponse != null && $registrationResponse->action == ResponseAction::Allow) {
// Valid registration attempt
$this->registerUser($request);
} else {
return new JsonResponse(["Registration denied; " . $registrationResponse->reasons[0] ]);
}# 1. Set the value of the DATADOME_FRAUD_API_KEY as an environment variable.
export DATADOME_FRAUD_API_KEY='FRAUD_API_KEY'
# 2. Add the required import in your controller.
require 'datadome_fraud_sdk_ruby'
# 3. Create a DataDome instance.
datadome = DataDome.new
# 4a. If you have access to the HTTP request as `request`:
# Invoke the validate and collect methods.
user_address = DataDomeAddress.new(name:'Home', line1: '123 Maple Street', line2: '2nd floor', city: 'Anytown',country_code: 'FR',region_code: 'PA', zip_code:'17101')
user_datadome = DataDomeUser.new(id: user.id, title: Title::MR, first_name: 'John',last_name: 'Doe', created_at: Time.now.iso8601, phone: '+33978787878', email: params[:user][:email], address: user_address)
datadome_session = DataDomeSession.new(id: '33')
#user_datadome = DataDomeUser.new(id: params[:user][:email])
if registration.success?
registration_event = DataDomeRegistrationEvent.new(account: params[:user][:email], user: user_datadome, status: DataDomeStatusType::SUCCEEDED, session: datadome_session )
datadome_response = datadome.validate(request: request, event: registration_event)
if datadome_response.action == DataDomeResponseAction::ALLOW
# implement logic
else
# implement logic
end
else
registration_event = DataDomeRegistrationEvent.new(account: params[:user][:email], user: user_datadome, status: DataDomeStatusType::FAILED)
datadome.collect(request: request, event: registration_event)
# 4b. If you can't pass the current HTTP request to our SDK:
# i. Create DataDomeHeaders and DataDomeRequest with request information
datadome_headers = DataDomeHeaders.new(addr: "1.1.1.1", client_ip: "1.1.1.1", content_type: "text", host: "https://example.com", port: 80, x_real_ip: "1.1.1.1", x_forwarded_for_ip: "1.1.1.1", accept_encoding: "gzip, deflate, br", accept_language: "fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4", accept: "*/*", method: "POST", protocol: "https", server_hostname: "example.com", referer: "https://example.com", user_agent:"curl", from: "[email protected]", request:"/login", origin: "https://example.com", accept_charset: "utf-8, iso-8859-1;q=0.7", connection: "keep-alive", client_id: "")
datadome_request = DataDomeRequest.new(datadome_headers)
## ii. Use the code from 4a and replace the request with datadome_request.
datadome_response = datadome.validate(request: datadome_request, event: registration_event)
datadome.collect(request: datadome_request, event: registration_event)package main
import (
"log"
"net/http"
"time"
dd "github.com/datadome/fraud-sdk-go-package/v2"
)
func addOpt[T any](opts []T, opt T, err error) []T {
if err != nil {
log.Printf("option error: %v", err)
return opts
}
return append(opts, opt)
}
func registrationHandler(client *dd.Client) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
_ = r.ParseForm()
name := "HQ"
line1 := "22 rue de la Michodiere"
line2 := "2nd floor"
city := "Paris"
countryCode := "FR"
regionCode := "75"
zipCode := "75002"
userAddress := dd.UserAllOfAddress{
City: &city,
CountryCode: &countryCode,
Line1: &line1,
Line2: &line2,
Name: &name,
RegionCode: ®ionCode,
ZipCode: &zipCode,
}
authentication := dd.RegistrationPayloadAllOfAuthentication{
Mode: dd.AuthenticationModePassword,
SocialProvider: dd.AuthenticationSocialProviderGoogle,
Type: dd.AuthenticationTypeSocial,
}
createdAt := time.Now().Format(time.RFC3339)
firstName := "Data"
lastName := "Dome"
title := dd.MRS
phone := "+33978787878"
email := r.FormValue("email")
displayName := "DataDome"
description := "Some Description"
user := dd.RegistrationPayloadAllOfUser{
Id: "fake_user_id",
Address: &userAddress,
CreatedAt: &createdAt,
Email: &email,
FirstName: &firstName,
LastName: &lastName,
Phone: &phone,
Title: &title,
DisplayName: &displayName,
Description: &description,
ExternalUrls: []string{
"https://example.org/external1",
"https://example.org/external2",
"https://example.org/external3",
},
PictureUrls: []string{
"https://example.org/image1.png",
"https://example.org/image2.png",
"https://example.org/image3.png",
},
}
sessionId := "sessionId"
session := dd.Session{
Id: &sessionId,
CreatedAt: &createdAt,
}
var opts []dd.RegistrationPayloadOption
authOpt, err := dd.RegistrationPayloadWithAuthentication(authentication)
opts = addOpt(opts, authOpt, err)
sessionOpt, err := dd.RegistrationPayloadWithSession(session)
opts = addOpt(opts, sessionOpt, err)
op, err := dd.NewValidateRegistration(email, user, opts...)
if err != nil {
log.Printf("error creating validate registration operation: %v\n", err)
http.Error(w, "invalid request", http.StatusBadRequest)
return
}
validate, err := op.PerformOperation(r.Context(), client, r, nil)
if err != nil {
log.Printf("error during validation: %v\n", err)
}
if validate.Action == dd.ALLOW {
w.WriteHeader(http.StatusOK)
return
} else {
// Business Logic here
http.Error(w, "failed", http.StatusForbidden)
return
}
}
}
}
func main() {
client, _ := dd.NewClient("FRAUD_API_KEY")
mux := http.NewServeMux()
mux.HandleFunc("/register", registrationHandler(client))
_ = http.ListenAndServe(":8080", mux)
}API Reference
RegistrationEvent
RegistrationEventThe SDK exposes methods for registration validation that require a RegistrationEvent instance to be sent to the Account Protect API along with the client request itself.
Available properties for this event type are listed below:
| Name | Description | Default Value | Possible Values | Optional |
|---|---|---|---|---|
| account | The unique account identifier used for the login attempt. | Any string value. | No | |
| authentication.mode | Authentication mode | biometric, mail mfa, otp, password, other | Yes | |
| authentication.socialProvider | Authentication social provider | amazon, apple, facebook, github, google, linkedin, microsoft, twitter, yahoo, other | Yes | |
| authentication.type | Authentication type | local, socialProvider, other | Yes | |
| accountType | Describe the type of the account | guest, staff,external,partner, customer, merchant, vip, test, other | Yes | |
| customFields | See dedicated custom fields section in the FAQ | |||
| failReason | Reason why the registration failed | duplicateAccount, invalidMfa, cancelled, internalBusinessRule, technicalIssue, other | ||
| partnerId | Identify the partner using the solution. | Any string value. | ||
| session.createdAt | Creation date of the session | Format ISO 8601 YYYY-MM-DDThh:mm:ssTZD | Yes | |
| session.id | A unique session identifier from your system | Any string value. | Yes | |
| status | Registration status | attempted, succeeded, failed | ||
| user.address.city | City of the address | Any string value. | Yes | |
| user.address.countryCode | Country of the address | Format ISO-3166-1-alpha-2 | Yes | |
| user.address.line1 | Line 1 of the address | Any string value. | Yes | |
| user.address.line2 | Line 2 of the address | Any string value. | Yes | |
| user.address.regionCode | Region code | Yes | ||
| user.address.zipCode | Zip code | Yes | ||
| user.createdAt | Creation date of the user | Format ISO 8601 YYYY-MM-DDThh:mm:ssTZD | Yes | |
| user.description | Description or biography of the user | Any string value. | Yes | |
| user.displayName | Display name of the user | Any string value. | Yes | |
| user.email | Email of the user | Valid email address | Yes | |
| user.externalUrls | External URLs of the user | An array of valid URL address (max 10 items) | Yes | |
| user.firstName | First name of the user | Any string value. | Yes | |
| user.id | A unique customer identifier from your system. It has to be the same for all other event sent | Any string value. | No | |
| user.lastName | Last name of the user | Any string value. | Yes | |
| user.phone | Phone of the user | E.164 format including + and a region code Example : example +33978787878 | Yes | |
| user.pictureUrls | Pictures of the user | An array of valid URL address (max 10 items) | Yes | |
| user.title | Title of the user | mr, mrs, mx | Yes | |
| user.dateOfBirth | Date of birth of the user | Format ISO 8601 YYYY-MM-DDThh:mm:ssTZD |
Validation Response
Validating a login event should result in a response that can include the following properties:
| Name | Description | Possible Values | Always Defined |
|---|---|---|---|
| action | The recommended action to perform on the login attempt. | allow, deny, review, challenge | Yes |
| errors | A list of objects representing each error with details. Each object will have the properties listed below. | ||
| errors[i].error | A short description of the error. | ||
| errors[i].field | The name of the value that triggered the error. | ||
| eventId | Event identifier associated to this validate event. | A valid UUID. | Yes |
| ip | The IP address detected as the origin of the client request. | ||
| message | A description of the error if the status is failure or timeout. | Invalid header / Request timed out... | |
| reasons | A list of reasons to support the recommended action. | List of reasons (Any string value.) | |
| score | The level of confidence when identifying a request as coming from a fraudster. Only available in Ruby SDK 2.1.0+, Go SDK v1.1.0+, and Node.js SDK 2.0.0+ | Integer | No |
| status | The status of the request to the Account Protect API. | ok, failure, timeout | Yes |
Options
Options can be applied to the SDK during its instantiation.
| Option Name | Description | Default Value |
|---|---|---|
| endpoint | The endpoint to call for the Account Protect API. | https://account-api.datadome.co |
| timeout | A timeout threshold in milliseconds. When an API request times out, the SDK will allow it by default. | 1500 |
You can find usage examples for each platform below:
const instance = new DataDome(apiKey, {
timeout: 1500,
endpoint: 'https://account-api.datadome.co',
});// appsettings.json
// The API key is always required, but can also be passed as
// an environment variable named DataDome__FraudAPIKey
"DataDome": {
"FraudAPIKey": "----",
"Timeout": 1500,
"Endpoint": "https://account-api.datadome.co"
}new DataDomeFraudService(datadomeFraudApiKey,
DataDomeOptions.newBuilder()
.endpoint("https://account-api.datadome.co")
.timeout(1500)
.build()
);datadome_instance = DataDome("FraudAPIKey", timeout=1500, endpoint="https://account-api.datadome.co")val dataDomeFraudService = new DataDomeFraudService(datadomeFraudApiKey,
DataDomeOptions.newBuilder()
.endpoint("https://account-api.datadome.co")
.timeout(1500)
.build()
)// .env
DATADOME_FRAUD_API_KEY='----'
DATADOME_TIMEOUT=1500
DATADOME_ENDPOINT='https://account-api.datadome.co'// .env
DATADOME_FRAUD_API_KEY='----'
DATADOME_TIMEOUT=1500
DATADOME_ENDPOINT='https://account-api.datadome.co'datadome = DataDome.new(1500, 'https://account-api.datadome.co', config.logger)client, err := dd.NewClient(
"FRAUD_API_KEY",
dd.ClientWithEndpoint("account-api.datadome.co"),
dd.ClientWithTimeout(1500),
)FAQ
What happens if there is a timeout on API request?
The SDK has been designed to have minimal impact on the user experience. If the configured timeout is reached, the SDK will cancel its pending operation and allow the application to proceed.
What happens if the API returns an error?
Errors and timeouts are handled the same way by the SDK: it will not interrupt the application and allow it to proceed.
What happens if my API key is incorrect?
Invalid keys are detected when calling the account protect API. The SDK will return an allow response to avoid blocking any login or registration attempt on the application. This response will also have a failure status and a message that describes the problem.
What are Custom Fields
Custom fields allow to send additional data. Up to 10 custom fields can be defined.
Each field is defined by the following
| name | type | description | Required |
|---|---|---|---|
| name | string | name of the custom field | Yes |
| value | string | Yes | |
| type | string | values: Number, String, Phone, email, userId, IP | No |
| isPii | boolean | trueif value contains Personally Identifiable Information | No |
Data type Phone must respect the E.164 format
Updated 16 days ago

