Sign In

API Reference

All endpoints are protected by basic authentication. This means setting an Authorization header with the value Basic :<<SECRET>> where <<SECRET>> is your API secret encoded with Base64. If the authorization header is missing or incorrect, the API will respond with 401.

The API only understands JSON requests and requires the Content-Type header to be set to application/json in requests with a body, such as POST or PUT.

Castle supports TLS version 1.1 and higher.

Failed requests

Successful response codes and payloads are documented per each endpoint, but errors are generalized into these codes: 401, 422, 500.

Error Code Description
401 Unauthorized You are missing the Authorization header, or the API secret is missing or incorrect.
422 Unprocessable Entity The request body is unprocessable by the API. Make sure it conforms to the specified format for the endpoint.
500 Internal Server Error There’s an issue on our end.

/v1/authenticate

Track a an event from your system with the API, and get a recommended action back. The most obvious use of this is for login requests, where the API can indicate malicious and questionable circumstances, but it can be used for any event. Note that the request payload schema matches that of /v1/track.

Method : POST

Request Payload Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  {
    "sent_at": "2018-07-10T17:37:39.123Z", // When the request was sent
    "event": "$login.succeeded",
    "user_id": "e325bcdd10ac", // Your internal user ID
    "user_traits": {
      "email": "johan@castle.io",
      "registered_at": "2018-07-10T17:37:39.123Z" // ISO 8601 format of user's account creation timestamp
    },
    "properties": {
      // You can optionally add information here.
      "event": "property"
    },
    "context": {
      "client_id": "faf117b2-9457-4e3b-9c13-d2795656b78e-094e81caa170c1d2", // You'll generally get this from the cookie created by c.js.
      "ip": "37.46.187.90", // The external IP of the incoming request (not the IP of your internal proxy).
      "headers": {
        // The headers of the incoming request. For security reasons, avoid sending the cookie header.
        "User-Agent": "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko",
        "Accept": "text/html",
        "Accept-Language": "en-us,en;q=0.5",
        "Accept-Encoding": "gzip, deflate, br",
        "Connection": "Keep-Alive",
        "Content-Length": "122",
        "Content-Type": "application/javascript",
        "Origin": "https://castle.io/",
        "Referer": "https://castle.io/login"
      }
    }
  }

Successful Response

Code : 201 CREATED

1
2
3
4
5
  {
    "action": "allow",
    "user_id": "123",
    "device_token": "ey..."
  }

Possible values of action are allow, challenge, deny.


/v1/track

Track an event from your system with the API. This endpoint doesn’t provide a response.

Method : POST

Request payload

Matches that of /v1/authenticate.

Successful Response

Code : 204 NO CONTENT

Provides no response body.


/v1/users/{user-id}/devices

Using a user ID, get all devices associated with that user.

Method : GET

Successful Response

Code : 200 OK

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  {
    "total_count": 2,
    "data": [
      {
        "token": "eyJhbGciOiJIUzI1NiJ9.eyJ0b2tlbiI6IkZSWHZnc3pvRWNHejNXYzVic1pjUHBjV3NzRXF1NDhqIiwidmVyc2lvbiI6MC4xfQ.AI5m5rUf97KZQg4o0zITwhNtbdgiAN9C2p3soDTg4sQ",
        "risk": 0.000154,
        "created_at": "2018-06-15T16:36:22.916Z",
        "last_seen_at": "2018-07-19T23:09:29.681Z",
        "approved_at": null,
        "escalated_at": null,
        "mitigated_at": null,
        "context": {
          "ip": "74.102.236.7",
          "location": {
            "country_code": "US",
            "country": "United States",
            "region": "New Jersey",
            "region_code": "NJ",
            "city": "Lyndhurst",
            "lat": 40.7923,
            "lon": -74.1001
          },
          "user_agent": {
            "raw": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36 OPR/54.0.2952.51",
            "browser": "Opera",
            "version": "54.0.2952",
            "os": "Mac OS X 10.13.6",
            "mobile": false,
            "platform": "Mac OS X",
            "device": "Unknown",
            "family": "Opera"
          },
          "type": "desktop"
        }
      },
      {
        "token": "eyJhbGciOiJIUzJ1NiJ9.eyJ0b2tlbiI6InhDb0hmd3h6VlZlbWR0NEN0Wlk4eGhrc0pHeldnMjdFIiwidmVyc2lvbiI6MC4xfQ.8Ll1-hR-hDjIAO27DgllWllQP6u2XG_syZayU_6FG80",
        "risk": 0.560931,
        "created_at": "2018-06-05T20:54:12.416Z",
        "last_seen_at": "2018-06-05T20:54:12.416Z",
        "approved_at": null,
        "escalated_at": null,
        "mitigated_at": null,
        "context": {
          "ip": "193.106.230.209",
          "location": {
            "country_code": "US",
            "country": "United States",
            "region": "California",
            "region_code": "CA",
            "city": "Goleta",
            "lat": 34.5021,
            "lon": -120.1287
          },
          "user_agent": {
            "raw": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:60.0) Gecko/20100101 Firefox/60.0",
            "browser": "Firefox",
            "version": "60.0",
            "os": "Mac OS X 10.13",
            "mobile": false,
            "platform": "Mac OS X",
            "device": "Unknown",
            "family": "Firefox"
          },
          "type": "desktop"
        }
      }
    ]
  }

/v1/devices/:device_token

Using a device token, get information about that device.

Method : GET

Successful Response

Code: 200 OK

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
  {
    "token": "19a0g9Hn84vkNSvRG6F9qM4j",
    "object": "device",
    "created_at": "2017-12-28T17:22:40.556Z",
    "last_seen_at": "2018-06-11T17:10:26.928Z",
    "approved_at": null,
    "escalated_at": "2018-06-12T17:10:26.928Z",
    "mitigated_at": null,
    "risk": 1.0,
    "context": {
      "type": "desktop",
      "ip": "162.12.41.13",
      "user_agent": {
        "raw": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko)",
        "browser": "Chrome",
        "version": "42.0.2311",
        "os": "Mac OS X 10.9.5",
        "mobile": false,
        "platform": "Mac OS X",
        "device": "Unknown",
        "family": "Chrome"
      },
      "location": {
        "street": null,
        "city": "San Francsico",
        "postal_code": 94107,
        "region": "CA",
        "country": "US",
        "lon": -122.3870544,
        "lat": 37.8019832
      }
    }
  }

/v1/devices/:device_token/approve

Approve a device using its device token.

Method : PUT

Successful Response

Code : 200 OK

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
  {
    "token": "19a0g9Hn84vkNSvRG6F9qM4j",
    "object": "device",
    "created_at": "2017-12-28T17:22:40.556Z",
    "last_seen_at": "2018-06-11T17:10:26.928Z",
    "approved_at": null,
    "escalated_at": "2018-06-12T17:10:26.928Z",
    "mitigated_at": null,
    "risk": 0.0,
    "context": {
      "type": "desktop",
      "ip": "162.12.41.13",
      "user_agent": {
        "raw": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko)",
        "browser": "Chrome",
        "version": "42.0.2311",
        "os": "Mac OS X 10.9.5",
        "mobile": false,
        "platform": "Mac OS X",
        "device": "Unknown",
        "family": "Chrome"
      },
      "location": {
        "street": null,
        "city": "San Francsico",
        "postal_code": 94107,
        "region": "CA",
        "country": "US",
        "lon": -122.3870544,
        "lat": 37.8019832
      }
    }
  }

/v1/devices/:device_token/report

Report a device using its device token.

Method : PUT

Successful Response

Code : 200 OK

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
  {
    "token": "19a0g9Hn84vkNSvRG6F9qM4j",
    "object": "device",
    "created_at": "2017-12-28T17:22:40.556Z",
    "last_seen_at": "2018-06-11T17:10:26.928Z",
    "approved_at": null,
    "escalated_at": "2018-06-12T17:10:26.928Z",
    "mitigated_at": null,
    "risk": 1.0,
    "context": {
      "type": "desktop",
      "ip": "162.12.41.13",
      "user_agent": {
        "raw": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko)",
        "browser": "Chrome",
        "version": "42.0.2311",
        "os": "Mac OS X 10.9.5",
        "mobile": false,
        "platform": "Mac OS X",
        "device": "Unknown",
        "family": "Chrome"
      },
      "location": {
        "street": null,
        "city": "San Francsico",
        "postal_code": 94107,
        "region": "CA",
        "country": "US",
        "lon": -122.3870544,
        "lat": 37.8019832
      }
    }
  }

/v1/impersonate

Inform Castle that some part of your support team is impersonating a user, to prevent us from tracking it as real activity.

Method : POST

Request Payload Example

1
2
3
4
5
6
7
8
9
  {
    "user_id": "1234",
    "impersonator": "optional_admin_id_or_email",
    "context": {
      "client_id": "a97b492d-dcc3-4fc1-87d6-65682955afa5",
      "ip": "37.46.187.90",
      "user-agent": "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"
    }
  }

Successful Response

Code : 200 OK

Has no content.


List of Recognized Events

This is a complete list of events recognized by the track and authenticate endpoints. Custom event names can be used, but primarily for your own use.

Name Description
$login.succeeded Record when a user succesfully logs in.
$login.failed Record when a user failed to log in.
$logout.succeeded Record when a user logs out.
$profile_update.succeeded Record when a user updated their profile (including password, email, phone, etc).
$profile_update.failed Record errors when updating profile.
$registration.succeeded Capture account creation, both when a user signs up as well as when created manually by an administrator.
$registration.failed Record when an account failed to be created.
$password_reset.succeeded The user completed all of the steps in the password reset process and the password was successfully reset. Password resets do not required knowledge of the current password.
$password_reset.failed Use to record when a user failed to reset their password.
$password_reset_request.succeeded The user successfully requested a password reset.
$password_reset_request.failed The user failed to request a password reset.
$incident.mitigated User account has been reset.
$review.escalated User confirmed malicious activity.
$review.resolved User confirmed safe activity.
$challenge.requested Record when a user is prompted with additional verification, such as two-factor authentication or a captcha.
$challenge.succeeded Record when additional verification was successful.
$challenge.failed Record when additional verification failed.
$transaction.attempted Record when a user attempts an in-app transaction, such as a purchase or withdrawal.
$session.extended Record when a user session is extended, or use any time you want to re-authenticate a user mid-session.