POST /v1/risk
Score a booking attempt and get back a decision.
Score one booking attempt. Call this from your server right before you commit the reservation.
| Method | POST |
| URL | https://api.staysignals.com/v1/risk |
| Auth | X-StaySignals-Key: sk_abc123def456… |
| Content-Type | application/json |
Request body
Send as much of this payload as you can. Only the fields marked required are strictly needed, but more context helps StaySignals make a sharper decision.
collectionId
The browser collection ID from staysignals.js.
| Field | Type | Required | Description |
|---|---|---|---|
collectionId | string | — | The collection ID for the current browser tab, when available (e.g. col_9f2a1c7b2e8d4a1f). Read it with window.StaySignals.getCollectionId() on the client and forward it to your server. |
booker (required)
The person placing the booking.
| Field | Type | Required | Description |
|---|---|---|---|
booker.referenceId | string | — | Your own internal identifier for this booker, if you have one (e.g. usr_8a21). |
booker.firstName | string | yes | Given name (e.g. Grace). |
booker.lastName | string | yes | Family name (e.g. Hopper). |
booker.email | string | yes | Email address (e.g. grace@example.com). |
booker.phone | string | yes | Phone number in E.164 format (e.g. +15125550125). |
guests
The named guests staying at the hotel. Always an array, even for a single guest.
If you collect only the primary guest's name, send that one guest here. Use booking.groupSize for the full party size when the search or reservation includes more adults, children, or infants. Omit any zero-count group size fields. If booking.groupSize is omitted, StaySignals uses guests.length as the displayed group size.
| Field | Type | Required | Description |
|---|---|---|---|
guests[].firstName | string | — | Given name (e.g. Alan). |
guests[].lastName | string | — | Family name (e.g. Kay). |
billing
The billing address used at checkout.
| Field | Type | Required | Description |
|---|---|---|---|
billing.addressLine | string | — | Street address (e.g. 221 Congress Ave). |
billing.country | string | — | ISO 3166-1 alpha-2 country code (e.g. US). |
hotel (required)
The property being booked.
| Field | Type | Required | Description |
|---|---|---|---|
hotel.referenceId | string | — | Your own internal identifier for the property (e.g. hot_4fd1). |
hotel.giataId | string | — | The GIATA property ID. Strongly recommended for property matching (e.g. 123456). |
hotel.name | string | yes | Property name (e.g. The Gravel House). |
hotel.address | string | — | Street address of the property (e.g. 501 E 6th St, Austin, TX). |
hotel.country | string | yes | ISO 3166-1 alpha-2 country code (e.g. US). |
booking (required)
The reservation details.
| Field | Type | Required | Description |
|---|---|---|---|
booking.checkIn | string | yes | Check-in date, YYYY-MM-DD (e.g. 2026-06-15). |
booking.checkOut | string | yes | Check-out date, YYYY-MM-DD (e.g. 2026-06-17). |
booking.groupSize.adultCount | integer | — | Number of adults in the party (e.g. 1). Omit when zero. |
booking.groupSize.childCount | integer | — | Number of children in the party (e.g. 2). Omit when zero. |
booking.groupSize.infantCount | integer | — | Number of infants in the party (e.g. 1). Omit when zero. |
requestId (required)
| Field | Type | Required | Description |
|---|---|---|---|
requestId | string | yes | Your own correlation id for this call. Echoed back in errors and stored on the decision record for tracing. |
Response
| Field | Type | Description |
|---|---|---|
decisionId | string | Unique identifier for this decision, prefixed with dec_. Store it on the order record to look up the decision later in the Dashboard. |
riskScore | integer | Integer from 0 to 99. Higher means more suspicious. |
riskLevel | string | One of low, medium, high. Derived from riskScore via a fixed mapping — not affected by your risk setting. |
suggestedAction | string | One of allow, deny. How to route the checkout. See Handling the response. |
riskSetting | string | Which risk setting was active at the time of the decision — one of maximizeProtection, balanced, maximizeRevenue. |
decidedAt | string | ISO 8601 timestamp of when StaySignals scored the booking. |
Example
Request
curl https://api.staysignals.com/v1/risk \
-H "X-StaySignals-Key: sk_abc123def456…" \
-H "Content-Type: application/json" \
-d '{
"collectionId": "col_9f2a1c7b2e8d4a1f",
"booker": {
"referenceId": "usr_8a21",
"firstName": "Grace",
"lastName": "Hopper",
"email": "grace@example.com",
"phone": "+15125550125"
},
"guests": [
{ "firstName": "Alan", "lastName": "Kay" }
],
"billing": {
"addressLine": "221 Congress Ave",
"country": "US"
},
"hotel": {
"referenceId": "hot_4fd1",
"giataId": "123456",
"name": "The Gravel House",
"address": "501 E 6th St, Austin, TX",
"country": "US"
},
"booking": {
"checkIn": "2026-06-15",
"checkOut": "2026-06-17",
"groupSize": {
"adultCount": 1
}
},
"requestId": "req_8a21"
}'Response
{
"decisionId": "dec_8f2a1c7b2e8d",
"riskScore": 18,
"riskLevel": "low",
"suggestedAction": "allow",
"riskSetting": "balanced",
"decidedAt": "2026-04-24T08:27:33.000Z"
}