{
  "openapi": "3.1.0",
  "info": {
    "title": "silentVIP webhooks",
    "version": "1",
    "summary": "Signed event notifications silentVIP sends to your HTTPS endpoint.",
    "description": "A travel manager adds up to 5 endpoints under Integrations, Webhooks in the silentVIP portal, chooses the events for each, and copies its signing secret (shown once). silentVIP then POSTs one JSON event per delivery. Verify every delivery: silentVIP-Signature is t=<unix seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">, keyed with the whole secret (whsec_ included) as UTF-8. Reject a t more than a few minutes old, and use silentVIP-Event-Id (the event's id) to ignore a repeat. Answer with a 2xx status within 10 seconds. Timeouts, 429 and 5xx answers are retried with backoff for about half an hour; any other status, and any redirect, isn't. After 20 events in a row can't be delivered, the endpoint is turned off and the account's travel managers are emailed. Guide: https://www.silentvip.com/developers",
    "contact": {
      "name": "silentVIP support",
      "email": "support@silentvip.com",
      "url": "https://www.silentvip.com/developers"
    }
  },
  "jsonSchemaDialect": "https://spec.openapis.org/oas/3.1/dialect/base",
  "webhooks": {
    "request.created": {
      "post": {
        "operationId": "requestCreated",
        "summary": "A trip request was made (portal, app, live search or a group event)",
        "description": "A new trip request.",
        "parameters": [
          {
            "name": "silentVIP-Signature",
            "in": "header",
            "required": true,
            "description": "t=<unix seconds>,v1=<lowercase hex HMAC-SHA256 of \"<t>.<raw body>\" keyed with the endpoint's signing secret>.",
            "schema": {
              "type": "string",
              "pattern": "^t=\\d+,v1=[0-9a-f]{64}$"
            }
          },
          {
            "name": "silentVIP-Event-Id",
            "in": "header",
            "required": true,
            "description": "The event's id, the same on every attempt.",
            "schema": {
              "type": "string",
              "pattern": "^evt_[0-9a-f]{24}$"
            }
          },
          {
            "name": "User-Agent",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "const": "silentVIP-Webhooks/1"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RequestCreatedEvent"
              },
              "example": {
                "id": "evt_3f9a6c2e1d8b4a7f60e5c1d2",
                "type": "request.created",
                "created": "2026-11-20T15:04:05.123Z",
                "account": "acct_7c3e9a1f20b4d658",
                "data": {
                  "request_id": "req_8d2e61f0a4b9c7e1",
                  "kind": "company",
                  "status": "new",
                  "origin": "New York",
                  "destination": "London",
                  "start_date": "2026-12-07",
                  "end_date": "2026-12-11",
                  "traveler": {
                    "id": "trv_4f1c2a9e0b7d3c55",
                    "name": "Jordan Lee"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Received. Any 2xx status acknowledges the delivery; the body is ignored."
          },
          "default": {
            "description": "Not received. 429, 5xx and no answer within the time limit are retried; anything else, including a redirect, is not."
          }
        }
      }
    },
    "request.approved": {
      "post": {
        "operationId": "requestApproved",
        "summary": "An approver approved a selection or a change (the last step of a chain)",
        "description": "An approved selection, change or cancellation (the last step of a multi-level chain).",
        "parameters": [
          {
            "name": "silentVIP-Signature",
            "in": "header",
            "required": true,
            "description": "t=<unix seconds>,v1=<lowercase hex HMAC-SHA256 of \"<t>.<raw body>\" keyed with the endpoint's signing secret>.",
            "schema": {
              "type": "string",
              "pattern": "^t=\\d+,v1=[0-9a-f]{64}$"
            }
          },
          {
            "name": "silentVIP-Event-Id",
            "in": "header",
            "required": true,
            "description": "The event's id, the same on every attempt.",
            "schema": {
              "type": "string",
              "pattern": "^evt_[0-9a-f]{24}$"
            }
          },
          {
            "name": "User-Agent",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "const": "silentVIP-Webhooks/1"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RequestApprovedEvent"
              },
              "example": {
                "id": "evt_3f9a6c2e1d8b4a7f60e5c1d2",
                "type": "request.approved",
                "created": "2026-11-20T15:04:05.123Z",
                "account": "acct_7c3e9a1f20b4d658",
                "data": {
                  "request_id": "req_8d2e61f0a4b9c7e1",
                  "kind": "company",
                  "status": "in_progress",
                  "origin": "New York",
                  "destination": "London",
                  "start_date": "2026-12-07",
                  "end_date": "2026-12-11",
                  "traveler": {
                    "id": "trv_4f1c2a9e0b7d3c55",
                    "name": "Jordan Lee"
                  },
                  "approval_id": "apr_5e0a7b13c9d2f846",
                  "approval_kind": "selection",
                  "decided_at": "2026-11-20T15:04:05.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Received. Any 2xx status acknowledges the delivery; the body is ignored."
          },
          "default": {
            "description": "Not received. 429, 5xx and no answer within the time limit are retried; anything else, including a redirect, is not."
          }
        }
      }
    },
    "request.declined": {
      "post": {
        "operationId": "requestDeclined",
        "summary": "An approver didn't approve a selection or a change",
        "description": "A selection, change or cancellation that wasn't approved. The approver's note isn't included.",
        "parameters": [
          {
            "name": "silentVIP-Signature",
            "in": "header",
            "required": true,
            "description": "t=<unix seconds>,v1=<lowercase hex HMAC-SHA256 of \"<t>.<raw body>\" keyed with the endpoint's signing secret>.",
            "schema": {
              "type": "string",
              "pattern": "^t=\\d+,v1=[0-9a-f]{64}$"
            }
          },
          {
            "name": "silentVIP-Event-Id",
            "in": "header",
            "required": true,
            "description": "The event's id, the same on every attempt.",
            "schema": {
              "type": "string",
              "pattern": "^evt_[0-9a-f]{24}$"
            }
          },
          {
            "name": "User-Agent",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "const": "silentVIP-Webhooks/1"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RequestDeclinedEvent"
              },
              "example": {
                "id": "evt_3f9a6c2e1d8b4a7f60e5c1d2",
                "type": "request.declined",
                "created": "2026-11-20T15:04:05.123Z",
                "account": "acct_7c3e9a1f20b4d658",
                "data": {
                  "request_id": "req_8d2e61f0a4b9c7e1",
                  "kind": "company",
                  "status": "waiting",
                  "origin": "New York",
                  "destination": "London",
                  "start_date": "2026-12-07",
                  "end_date": "2026-12-11",
                  "traveler": {
                    "id": "trv_4f1c2a9e0b7d3c55",
                    "name": "Jordan Lee"
                  },
                  "approval_id": "apr_5e0a7b13c9d2f846",
                  "approval_kind": "selection",
                  "decided_at": "2026-11-20T15:04:05.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Received. Any 2xx status acknowledges the delivery; the body is ignored."
          },
          "default": {
            "description": "Not received. 429, 5xx and no answer within the time limit are retried; anything else, including a redirect, is not."
          }
        }
      }
    },
    "trip.booked": {
      "post": {
        "operationId": "tripBooked",
        "summary": "A trip was booked or confirmed",
        "description": "A trip that was booked, or confirmed by your silentVIP team.",
        "parameters": [
          {
            "name": "silentVIP-Signature",
            "in": "header",
            "required": true,
            "description": "t=<unix seconds>,v1=<lowercase hex HMAC-SHA256 of \"<t>.<raw body>\" keyed with the endpoint's signing secret>.",
            "schema": {
              "type": "string",
              "pattern": "^t=\\d+,v1=[0-9a-f]{64}$"
            }
          },
          {
            "name": "silentVIP-Event-Id",
            "in": "header",
            "required": true,
            "description": "The event's id, the same on every attempt.",
            "schema": {
              "type": "string",
              "pattern": "^evt_[0-9a-f]{24}$"
            }
          },
          {
            "name": "User-Agent",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "const": "silentVIP-Webhooks/1"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TripBookedEvent"
              },
              "example": {
                "id": "evt_3f9a6c2e1d8b4a7f60e5c1d2",
                "type": "trip.booked",
                "created": "2026-11-20T15:04:05.123Z",
                "account": "acct_7c3e9a1f20b4d658",
                "data": {
                  "trip_id": "trip_2b7c90d4e1f3a685",
                  "request_id": "req_8d2e61f0a4b9c7e1",
                  "status": "confirmed",
                  "destination": "London",
                  "start_date": "2026-12-07",
                  "end_date": "2026-12-11",
                  "travelers": [
                    "Jordan Lee"
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Received. Any 2xx status acknowledges the delivery; the body is ignored."
          },
          "default": {
            "description": "Not received. 429, 5xx and no answer within the time limit are retried; anything else, including a redirect, is not."
          }
        }
      }
    },
    "trip.changed": {
      "post": {
        "operationId": "tripChanged",
        "summary": "A booked trip's dates, destination or itinerary changed",
        "description": "A booked trip whose dates, destination, status or itinerary changed.",
        "parameters": [
          {
            "name": "silentVIP-Signature",
            "in": "header",
            "required": true,
            "description": "t=<unix seconds>,v1=<lowercase hex HMAC-SHA256 of \"<t>.<raw body>\" keyed with the endpoint's signing secret>.",
            "schema": {
              "type": "string",
              "pattern": "^t=\\d+,v1=[0-9a-f]{64}$"
            }
          },
          {
            "name": "silentVIP-Event-Id",
            "in": "header",
            "required": true,
            "description": "The event's id, the same on every attempt.",
            "schema": {
              "type": "string",
              "pattern": "^evt_[0-9a-f]{24}$"
            }
          },
          {
            "name": "User-Agent",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "const": "silentVIP-Webhooks/1"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TripChangedEvent"
              },
              "example": {
                "id": "evt_3f9a6c2e1d8b4a7f60e5c1d2",
                "type": "trip.changed",
                "created": "2026-11-20T15:04:05.123Z",
                "account": "acct_7c3e9a1f20b4d658",
                "data": {
                  "trip_id": "trip_2b7c90d4e1f3a685",
                  "request_id": "req_8d2e61f0a4b9c7e1",
                  "status": "confirmed",
                  "destination": "London",
                  "start_date": "2026-12-07",
                  "end_date": "2026-12-12",
                  "travelers": [
                    "Jordan Lee"
                  ],
                  "changed": [
                    "end_date",
                    "itinerary"
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Received. Any 2xx status acknowledges the delivery; the body is ignored."
          },
          "default": {
            "description": "Not received. 429, 5xx and no answer within the time limit are retried; anything else, including a redirect, is not."
          }
        }
      }
    },
    "trip.cancelled": {
      "post": {
        "operationId": "tripCancelled",
        "summary": "A trip was canceled",
        "description": "A trip that was canceled.",
        "parameters": [
          {
            "name": "silentVIP-Signature",
            "in": "header",
            "required": true,
            "description": "t=<unix seconds>,v1=<lowercase hex HMAC-SHA256 of \"<t>.<raw body>\" keyed with the endpoint's signing secret>.",
            "schema": {
              "type": "string",
              "pattern": "^t=\\d+,v1=[0-9a-f]{64}$"
            }
          },
          {
            "name": "silentVIP-Event-Id",
            "in": "header",
            "required": true,
            "description": "The event's id, the same on every attempt.",
            "schema": {
              "type": "string",
              "pattern": "^evt_[0-9a-f]{24}$"
            }
          },
          {
            "name": "User-Agent",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "const": "silentVIP-Webhooks/1"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TripCancelledEvent"
              },
              "example": {
                "id": "evt_3f9a6c2e1d8b4a7f60e5c1d2",
                "type": "trip.cancelled",
                "created": "2026-11-20T15:04:05.123Z",
                "account": "acct_7c3e9a1f20b4d658",
                "data": {
                  "trip_id": "trip_2b7c90d4e1f3a685",
                  "request_id": "req_8d2e61f0a4b9c7e1",
                  "status": "cancelled",
                  "destination": "London",
                  "start_date": "2026-12-07",
                  "end_date": "2026-12-11",
                  "travelers": [
                    "Jordan Lee"
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Received. Any 2xx status acknowledges the delivery; the body is ignored."
          },
          "default": {
            "description": "Not received. 429, 5xx and no answer within the time limit are retried; anything else, including a redirect, is not."
          }
        }
      }
    },
    "safety.needs_help": {
      "post": {
        "operationId": "safetyNeedsHelp",
        "summary": "A traveler answered a safety check-in saying they need help",
        "description": "A traveler answered a safety check-in saying they need help. Their message isn't included: open the incident in the portal.",
        "parameters": [
          {
            "name": "silentVIP-Signature",
            "in": "header",
            "required": true,
            "description": "t=<unix seconds>,v1=<lowercase hex HMAC-SHA256 of \"<t>.<raw body>\" keyed with the endpoint's signing secret>.",
            "schema": {
              "type": "string",
              "pattern": "^t=\\d+,v1=[0-9a-f]{64}$"
            }
          },
          {
            "name": "silentVIP-Event-Id",
            "in": "header",
            "required": true,
            "description": "The event's id, the same on every attempt.",
            "schema": {
              "type": "string",
              "pattern": "^evt_[0-9a-f]{24}$"
            }
          },
          {
            "name": "User-Agent",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "const": "silentVIP-Webhooks/1"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SafetyNeedsHelpEvent"
              },
              "example": {
                "id": "evt_3f9a6c2e1d8b4a7f60e5c1d2",
                "type": "safety.needs_help",
                "created": "2026-11-20T15:04:05.123Z",
                "account": "acct_7c3e9a1f20b4d658",
                "data": {
                  "incident_id": "inc_93c1d0e7a2b4f568",
                  "check_id": "chk_0f6e2d9c8b7a1354",
                  "traveler": {
                    "id": "trv_4f1c2a9e0b7d3c55",
                    "name": "Jordan Lee"
                  },
                  "channel": "app",
                  "answered_at": "2026-12-08T09:12:44.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Received. Any 2xx status acknowledges the delivery; the body is ignored."
          },
          "default": {
            "description": "Not received. 429, 5xx and no answer within the time limit are retried; anything else, including a redirect, is not."
          }
        }
      }
    },
    "incident.opened": {
      "post": {
        "operationId": "incidentOpened",
        "summary": "A safety incident was opened that your account can see",
        "description": "A safety incident your account can see was opened. Its details text isn't included.",
        "parameters": [
          {
            "name": "silentVIP-Signature",
            "in": "header",
            "required": true,
            "description": "t=<unix seconds>,v1=<lowercase hex HMAC-SHA256 of \"<t>.<raw body>\" keyed with the endpoint's signing secret>.",
            "schema": {
              "type": "string",
              "pattern": "^t=\\d+,v1=[0-9a-f]{64}$"
            }
          },
          {
            "name": "silentVIP-Event-Id",
            "in": "header",
            "required": true,
            "description": "The event's id, the same on every attempt.",
            "schema": {
              "type": "string",
              "pattern": "^evt_[0-9a-f]{24}$"
            }
          },
          {
            "name": "User-Agent",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "const": "silentVIP-Webhooks/1"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IncidentOpenedEvent"
              },
              "example": {
                "id": "evt_3f9a6c2e1d8b4a7f60e5c1d2",
                "type": "incident.opened",
                "created": "2026-11-20T15:04:05.123Z",
                "account": "acct_7c3e9a1f20b4d658",
                "data": {
                  "incident_id": "inc_93c1d0e7a2b4f568",
                  "title": "Rail strike",
                  "severity": "warning",
                  "places": [
                    "London",
                    "United Kingdom"
                  ],
                  "starts_on": "2026-12-08",
                  "ends_on": "2026-12-09",
                  "scope": "account"
                }
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Received. Any 2xx status acknowledges the delivery; the body is ignored."
          },
          "default": {
            "description": "Not received. 429, 5xx and no answer within the time limit are retried; anything else, including a redirect, is not."
          }
        }
      }
    },
    "ping": {
      "post": {
        "operationId": "ping",
        "summary": "A test event, sent when you choose Send test event",
        "description": "A test event, sent when a travel manager chooses Send test event.",
        "parameters": [
          {
            "name": "silentVIP-Signature",
            "in": "header",
            "required": true,
            "description": "t=<unix seconds>,v1=<lowercase hex HMAC-SHA256 of \"<t>.<raw body>\" keyed with the endpoint's signing secret>.",
            "schema": {
              "type": "string",
              "pattern": "^t=\\d+,v1=[0-9a-f]{64}$"
            }
          },
          {
            "name": "silentVIP-Event-Id",
            "in": "header",
            "required": true,
            "description": "The event's id, the same on every attempt.",
            "schema": {
              "type": "string",
              "pattern": "^evt_[0-9a-f]{24}$"
            }
          },
          {
            "name": "User-Agent",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "const": "silentVIP-Webhooks/1"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PingEvent"
              },
              "example": {
                "id": "evt_3f9a6c2e1d8b4a7f60e5c1d2",
                "type": "ping",
                "created": "2026-11-20T15:04:05.123Z",
                "account": "acct_7c3e9a1f20b4d658",
                "data": {
                  "endpoint_id": "whe_6a1b2c3d4e5f6071",
                  "message": "This is a test event from silentVIP."
                }
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Received. Any 2xx status acknowledges the delivery; the body is ignored."
          },
          "default": {
            "description": "Not received. 429, 5xx and no answer within the time limit are retried; anything else, including a redirect, is not."
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Event": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "type",
          "created",
          "account",
          "data"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^evt_[0-9a-f]{24}$",
            "description": "Unique per event; repeated in the silentVIP-Event-Id header and on every retry."
          },
          "type": {
            "type": "string",
            "enum": [
              "request.created",
              "request.approved",
              "request.declined",
              "trip.booked",
              "trip.changed",
              "trip.cancelled",
              "safety.needs_help",
              "incident.opened",
              "ping"
            ],
            "description": "The event type."
          },
          "created": {
            "type": "string",
            "format": "date-time",
            "description": "When the event happened (UTC)."
          },
          "account": {
            "type": "string",
            "description": "Your silentVIP account's id."
          },
          "data": {
            "type": "object",
            "description": "The event's data: see each event."
          }
        }
      },
      "Traveler": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name"
        ],
        "properties": {
          "id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The traveler profile's id."
          },
          "name": {
            "type": "string",
            "description": "Full name as on the profile."
          }
        }
      },
      "RequestCreatedEvent": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Event"
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "request.created"
              },
              "data": {
                "type": "object",
                "description": "A new trip request.",
                "additionalProperties": false,
                "required": [
                  "request_id",
                  "kind",
                  "status",
                  "origin",
                  "destination",
                  "start_date",
                  "end_date",
                  "traveler"
                ],
                "properties": {
                  "request_id": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9_-]{1,80}$",
                    "description": "The request's id."
                  },
                  "kind": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "company",
                      "personal",
                      "event",
                      "change",
                      "other"
                    ],
                    "description": "What kind of request it is."
                  },
                  "status": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "new",
                      "in_progress",
                      "waiting",
                      "done",
                      "cancelled"
                    ],
                    "description": "The request's status when the event happened."
                  },
                  "origin": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 80,
                    "description": "Where the trip starts, as entered (a city or airport). Null on a free-form request."
                  },
                  "destination": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 80,
                    "description": "Where the trip goes. Null on a free-form request."
                  },
                  "start_date": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date",
                    "description": "Departure date."
                  },
                  "end_date": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date",
                    "description": "Return date, if any."
                  },
                  "traveler": {
                    "oneOf": [
                      {
                        "$ref": "#/components/schemas/Traveler"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "The traveler the request is for, when it names one of your traveler profiles."
                  }
                }
              }
            }
          }
        ]
      },
      "RequestApprovedEvent": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Event"
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "request.approved"
              },
              "data": {
                "type": "object",
                "description": "An approved selection, change or cancellation (the last step of a multi-level chain).",
                "additionalProperties": false,
                "required": [
                  "request_id",
                  "kind",
                  "status",
                  "origin",
                  "destination",
                  "start_date",
                  "end_date",
                  "traveler",
                  "approval_id",
                  "approval_kind",
                  "decided_at"
                ],
                "properties": {
                  "request_id": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9_-]{1,80}$",
                    "description": "The request's id."
                  },
                  "kind": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "company",
                      "personal",
                      "event",
                      "change",
                      "other"
                    ],
                    "description": "What kind of request it is."
                  },
                  "status": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "new",
                      "in_progress",
                      "waiting",
                      "done",
                      "cancelled"
                    ],
                    "description": "The request's status when the event happened."
                  },
                  "origin": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 80,
                    "description": "Where the trip starts, as entered (a city or airport). Null on a free-form request."
                  },
                  "destination": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 80,
                    "description": "Where the trip goes. Null on a free-form request."
                  },
                  "start_date": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date",
                    "description": "Departure date."
                  },
                  "end_date": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date",
                    "description": "Return date, if any."
                  },
                  "traveler": {
                    "oneOf": [
                      {
                        "$ref": "#/components/schemas/Traveler"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "The traveler the request is for, when it names one of your traveler profiles."
                  },
                  "approval_id": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9_-]{1,80}$",
                    "description": "The approval's id."
                  },
                  "approval_kind": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "selection",
                      "change",
                      "cancellation"
                    ],
                    "description": "What was approved: the chosen option, a change, or a cancellation."
                  },
                  "decided_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time",
                    "description": "When it was decided."
                  }
                }
              }
            }
          }
        ]
      },
      "RequestDeclinedEvent": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Event"
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "request.declined"
              },
              "data": {
                "type": "object",
                "description": "A selection, change or cancellation that wasn't approved. The approver's note isn't included.",
                "additionalProperties": false,
                "required": [
                  "request_id",
                  "kind",
                  "status",
                  "origin",
                  "destination",
                  "start_date",
                  "end_date",
                  "traveler",
                  "approval_id",
                  "approval_kind",
                  "decided_at"
                ],
                "properties": {
                  "request_id": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9_-]{1,80}$",
                    "description": "The request's id."
                  },
                  "kind": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "company",
                      "personal",
                      "event",
                      "change",
                      "other"
                    ],
                    "description": "What kind of request it is."
                  },
                  "status": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "new",
                      "in_progress",
                      "waiting",
                      "done",
                      "cancelled"
                    ],
                    "description": "The request's status when the event happened."
                  },
                  "origin": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 80,
                    "description": "Where the trip starts, as entered (a city or airport). Null on a free-form request."
                  },
                  "destination": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 80,
                    "description": "Where the trip goes. Null on a free-form request."
                  },
                  "start_date": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date",
                    "description": "Departure date."
                  },
                  "end_date": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date",
                    "description": "Return date, if any."
                  },
                  "traveler": {
                    "oneOf": [
                      {
                        "$ref": "#/components/schemas/Traveler"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "The traveler the request is for, when it names one of your traveler profiles."
                  },
                  "approval_id": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9_-]{1,80}$",
                    "description": "The approval's id."
                  },
                  "approval_kind": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "selection",
                      "change",
                      "cancellation"
                    ],
                    "description": "What wasn't approved."
                  },
                  "decided_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time",
                    "description": "When it was decided."
                  }
                }
              }
            }
          }
        ]
      },
      "TripBookedEvent": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Event"
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "trip.booked"
              },
              "data": {
                "type": "object",
                "description": "A trip that was booked, or confirmed by your silentVIP team.",
                "additionalProperties": false,
                "required": [
                  "trip_id",
                  "request_id",
                  "status",
                  "destination",
                  "start_date",
                  "end_date",
                  "travelers"
                ],
                "properties": {
                  "trip_id": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9_-]{1,80}$",
                    "description": "The trip's id."
                  },
                  "request_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "pattern": "^[A-Za-z0-9_-]{1,80}$",
                    "description": "The request the trip was booked from, if any."
                  },
                  "status": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "planning",
                      "confirmed",
                      "completed",
                      "cancelled"
                    ],
                    "description": "The trip's status after the change."
                  },
                  "destination": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 80,
                    "description": "The trip's destination."
                  },
                  "start_date": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date",
                    "description": "First day of the trip."
                  },
                  "end_date": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date",
                    "description": "Last day of the trip."
                  },
                  "travelers": {
                    "type": "array",
                    "maxItems": 20,
                    "items": {
                      "type": "string"
                    },
                    "description": "Names on the trip that match one of your traveler profiles."
                  }
                }
              }
            }
          }
        ]
      },
      "TripChangedEvent": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Event"
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "trip.changed"
              },
              "data": {
                "type": "object",
                "description": "A booked trip whose dates, destination, status or itinerary changed.",
                "additionalProperties": false,
                "required": [
                  "trip_id",
                  "request_id",
                  "status",
                  "destination",
                  "start_date",
                  "end_date",
                  "travelers",
                  "changed"
                ],
                "properties": {
                  "trip_id": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9_-]{1,80}$",
                    "description": "The trip's id."
                  },
                  "request_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "pattern": "^[A-Za-z0-9_-]{1,80}$",
                    "description": "The request the trip was booked from, if any."
                  },
                  "status": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "planning",
                      "confirmed",
                      "completed",
                      "cancelled"
                    ],
                    "description": "The trip's status after the change."
                  },
                  "destination": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 80,
                    "description": "The trip's destination."
                  },
                  "start_date": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date",
                    "description": "First day of the trip."
                  },
                  "end_date": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date",
                    "description": "Last day of the trip."
                  },
                  "travelers": {
                    "type": "array",
                    "maxItems": 20,
                    "items": {
                      "type": "string"
                    },
                    "description": "Names on the trip that match one of your traveler profiles."
                  },
                  "changed": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "status",
                        "start_date",
                        "end_date",
                        "destination",
                        "itinerary"
                      ]
                    },
                    "description": "What changed. itinerary: a booking was added to the trip."
                  }
                }
              }
            }
          }
        ]
      },
      "TripCancelledEvent": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Event"
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "trip.cancelled"
              },
              "data": {
                "type": "object",
                "description": "A trip that was canceled.",
                "additionalProperties": false,
                "required": [
                  "trip_id",
                  "request_id",
                  "status",
                  "destination",
                  "start_date",
                  "end_date",
                  "travelers"
                ],
                "properties": {
                  "trip_id": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9_-]{1,80}$",
                    "description": "The trip's id."
                  },
                  "request_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "pattern": "^[A-Za-z0-9_-]{1,80}$",
                    "description": "The request the trip was booked from, if any."
                  },
                  "status": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "planning",
                      "confirmed",
                      "completed",
                      "cancelled"
                    ],
                    "description": "The trip's status after the change."
                  },
                  "destination": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 80,
                    "description": "The trip's destination."
                  },
                  "start_date": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date",
                    "description": "First day of the trip."
                  },
                  "end_date": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date",
                    "description": "Last day of the trip."
                  },
                  "travelers": {
                    "type": "array",
                    "maxItems": 20,
                    "items": {
                      "type": "string"
                    },
                    "description": "Names on the trip that match one of your traveler profiles."
                  }
                }
              }
            }
          }
        ]
      },
      "SafetyNeedsHelpEvent": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Event"
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "safety.needs_help"
              },
              "data": {
                "type": "object",
                "description": "A traveler answered a safety check-in saying they need help. Their message isn't included: open the incident in the portal.",
                "additionalProperties": false,
                "required": [
                  "incident_id",
                  "check_id",
                  "traveler",
                  "channel",
                  "answered_at"
                ],
                "properties": {
                  "incident_id": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9_-]{1,80}$",
                    "description": "The incident's id."
                  },
                  "check_id": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9_-]{1,80}$",
                    "description": "The traveler's check on that incident."
                  },
                  "traveler": {
                    "oneOf": [
                      {
                        "$ref": "#/components/schemas/Traveler"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Who needs help."
                  },
                  "channel": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "email",
                      "sms",
                      "phone",
                      "app"
                    ],
                    "description": "How the answer came in."
                  },
                  "answered_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time",
                    "description": "When they answered."
                  }
                }
              }
            }
          }
        ]
      },
      "IncidentOpenedEvent": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Event"
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "incident.opened"
              },
              "data": {
                "type": "object",
                "description": "A safety incident your account can see was opened. Its details text isn't included.",
                "additionalProperties": false,
                "required": [
                  "incident_id",
                  "title",
                  "severity",
                  "places",
                  "starts_on",
                  "ends_on",
                  "scope"
                ],
                "properties": {
                  "incident_id": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9_-]{1,80}$",
                    "description": "The incident's id."
                  },
                  "title": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 140,
                    "description": "The incident's title."
                  },
                  "severity": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "advisory",
                      "warning",
                      "critical"
                    ],
                    "description": "Severity."
                  },
                  "places": {
                    "type": "array",
                    "maxItems": 20,
                    "items": {
                      "type": "string"
                    },
                    "description": "Countries or cities it covers."
                  },
                  "starts_on": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date",
                    "description": "First day it covers."
                  },
                  "ends_on": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date",
                    "description": "Last day it covers, if set."
                  },
                  "scope": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "account",
                      "all_clients"
                    ],
                    "description": "account: raised for your account; all_clients: raised by silentVIP for every client."
                  }
                }
              }
            }
          }
        ]
      },
      "PingEvent": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Event"
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "ping"
              },
              "data": {
                "type": "object",
                "description": "A test event, sent when a travel manager chooses Send test event.",
                "additionalProperties": false,
                "required": [
                  "endpoint_id",
                  "message"
                ],
                "properties": {
                  "endpoint_id": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9_-]{1,80}$",
                    "description": "The endpoint the test was sent to."
                  },
                  "message": {
                    "type": "string",
                    "description": "Always \"This is a test event from silentVIP.\""
                  }
                }
              }
            }
          }
        ]
      }
    }
  }
}