Migrating from legacy APIs

A guide on how to migrate to the new Risk and Filter APIs.


On June 3, 2021, we launched a new set of API endpoints as well as 2.0 versions of our client-side SDKs. The new endpoints run a more comprehensive fraud detection model, as opposed to the legacy model that was mainly tuned to detect account takeovers.

Some of the benefits of upgrading:

  • risk scoring of account registrations and transactions based on a range of new fraud and abuse patterns, such as multi-accounting, device spoofing, and unusual app interactions. The old APIs supports these use-cases as well, but those risk models are mainly tuned to detect account takeover fraud
  • better identification of unique global devices through a new device fingerprinting algorithm. Exposes the unique fingerprint identifier in the event payload which allows for granular rules building
  • prevents bad actors from replaying client-side requests through a more secure and tamperproof client-side data collector
  • all events will appear in the Events view in the Castle dashboard, which is powered by a Query API that'll soon be exposed to the public and can be used to integrate Castle data into your own fraud tools. Currently, only events sent to /authenticate end up in this view
  • any future improvements to risk models and device fingerprinting will only be deployed to the new endpoints, unless they are bug fixes

Migration guide

Phase 1: Client-side

Update the client-side SDKs to the 2.0 version or later. The main difference is that the new server-side APIs will use the new Request Token, as opposed to the old Client ID. The web version, Castle.js, needs to be downloaded via NPM, not the CDN (which would get blocked by some privacy tools).

The new request_token string needs to be generated in the client right before any backend request that's going to be sent to Castle since it expires after 120 seconds. It will need to be present on 100% of your requests to Risk and Filter APIs (however, not Log API) so you should make sure this is verified before proceeding to the next step. Any missing request tokens will result in an API validation error.

Force your users to do an update of their apps next time they open the app so that all users will have the 2.0 of the Castle SDKs. If you're unable to do a force update, you'll need to make sure that either you don't send old requests to the Risk API since they'll trigger an error, alternatively, you use the Log API to log these events to the user timeline without performing any risk scoring.


Note that you can send the new request_token to the legacy endpoints as client_id while you're going through the client-side upgrade. Once the upgrade is completed, the old APIs will be disabled for your account.

Phase 2: Upgrade your environment

Contact [email protected] and we will help you validate that your new client-side request tokens are forwarded to our API, and we'll then migrate your environment to the new risk model.

Phase 3: Server-side

Once you've validated that 100% of your requests now contain the new request token as opposed to the Client ID, you're ready to switch over to the new APIs:

  • /v1/risk -- Similar to calling /v1/authenticate with user_id. See the API reference.
  • /v1/filter -- Similar to calling /v1/authenticate without user_id. See the API reference.
  • /v1/log -- Similar to calling /v1/track but with no risk score or signals generated. See the API reference. This endpoint does not require the request_token, so it should allow some more flexibility, however; as a result it does not calculate a risk score.


The new APIs will return an error when the request_token (previously client_id) is missing or invalid, so it's important that you validate that it's present on 100% of your requests before migrating.

Updates to the request payload


The new APIs require you to send either user.email or user.phone. These fields used to be optional.

Old fieldNew fieldComment
eventtypeFormat changed from $login.succeeded to $login
N/AstatusThe last part of the old event, e.g. $succeeded
context.client_idrequest_tokenRequires version 2.0 of the client SDKs. Will generate a request error when invalid.
user_iduser.idAttribute moved
user_traitsuser.traitsObject moved
user_traits.emailuser.emailAttribute moved
user.phoneAttribute introduced
user_traits.nameuser.nameAttribute moved
user_traits.registered_atuser.registered_atAttribute moved

Updates to the response payload

Old formatNew formatComment

Other changes in functionality

  • Page views have been deprecated (for now), so the identify and page calls on the frontend will no longer work. The frontend integration will be back in early Q1.
  • Impersonation Mode has been deprecated. You should instead make sure you disable Castle when your support team impersonate customers, and if you want to keep track of impersonation events in Castle, simply send a custom event to /log and call it something like "User was impersonated by Lisa R.".
  • The $password_reset event has been deprecated. If you've previously used it to recover user accounts after an account takeover, you should instead use the /users/:id/recover call which will archive any reported devices. If you also want to keep track of the actual password update event, send a $profile_update event with properties.password_update = true.
  • Custom events (i.e. events not starting with $) should be sent as type: "$custom" with name: "Your Custom Name"
  • The $session.extended event has been deprecated. Instead send a custom event such as name: "Session Extended"

Did this page help you?