FareHarbor Integration Center (1.0)
Download OpenAPI specification:Download
A webhook is an HTTPS request sent from FareHarbor to a server of your choice as a result of an event.
FareHarbor can send webhooks when bookings are created, updated, rebooked, or cancelled, when a contact changes, when a checkin occurs, when items are updated, when crew members are created, updated, or deleted, etc.
For ideas about how to use webhooks in concert with the External API, see FAQ and Best Practices.
You can provide two webhook URLs to FareHarbor: one for production webhooks and one for test webhooks.
Contact support@fareharbor.com to configure these.
(Note: The server for the production webhook URL must have a valid SSL certificate. If it doesn't have one, then the webhook will not be delivered. It is up to you to ensure that your SSL certificates get renewed as needed.)
(Note: Companies in demo mode do not trigger webhooks.)
Your server should respond to the webhook with an HTTP success response code. If FareHarbor receives an HTTP error response or no response at all, then the webhook will be retried some number of times, with a significant pause between attempts. If FareHarbor detects too many failures (non-200 statuses) within a short period of time, we may deactivate the webhook and contact you.
When a booking-related event occurs, FareHarbor sends a POST
request to
the webhook URL that you have provided.
Depending on how your webhooks are configured, these POST
requests will be sent for:
- all changes to bookings (including creations, modifications, and cancellations);
- creations only; or
- cancellations only.
The body of this request contains an up-to-date JSON representation of the booking.
There are four booking data types that can be sent to a webhook: A full set of data contained in the booking fields, as well as optimized versions of each type to reduce the amount of fields, thereby decreasing the amount of data you need to store and process (filter).
- Bookings only (default setting). The data returned in this data type includes: Contact Name, Phone, Email, Activity, Availability, Customer Types, Custom Fields, Subtotal, Tax, Total and Amount paid from a booking. Note that payment and refund information is not included with this data type.
- Bookings only (Optimized): This data type returns a smaller group of fields as compared to Bookings only, in order to improve performance and give you only the data that is of most importance to you. Note that these fields also do not include payment or refund information. The following data fields are returned using this data type: Item, Company, Contact, Availability, Customers, Custom field values, Effective cancellation policy, Invoice, Receipt, Amount paid, Agent, Desk, Status and Rebooked.
- Bookings + payments: If you want to send payment and refund data, in addition to what is sent with Bookings only, select this type for all bookings fields and including payment information.
- Bookings + payments (Optimized): Use this data type when you want to receive a subset of bookings data, as compared to the full Bookings + payments output. The data returned for the optimized call will also include payment and refund information. Sending data using an optimized connection can enhance server performance during the API call by filtering out only the most frequently used fields. This will also allow you to more effectively manage only the data that is of interest.
- Create custom booking schema: This data type allows you to customize what specific booking data will be included. You can update the included booking data for a custom webhook at any time by clicking the webhook’s Edit option under the Webhook tab.
Some of the fields are described here.
Depending how your webhook is configured and what fields you are
allowed to view, there may also be a payments
property:
{
"booking": {
"pk": 456,
"payments": [
{
"amount_paid": 1939,
"amount_paid_display": "19.39",
"created_at": "2020-07-23T14:43:30-1000",
"currency": "usd",
"initial_amount_paid": 2154,
"initial_amount_paid_display": "21.54",
"pk": 6234,
"refunds": [
{
"amount_refunded": 215,
"amount_refunded_display": "2.15",
"created_at": "2020-07-23T14:43:41-1000",
"is_cancelled": false,
"pk": 1123
}
],
"status": "succeeded",
"type": "affiliate",
"in_store_payment_type": {
"pk": 137,
"name": "Cash"
}
}
],
...
}
}
When the payment is type: "in-store"
, the in_store_payment_type
in
the response has the pk and name of the in-store payment type.
When the payment is type: "affiliate"
and the payment is an
affiliate in-store payment, the in_store_payment_type
in the
response has the pk of the in-store payment type and may have the name
as well.
When the payment is not an in-store payment, the
in_store_payment_type
in the response is null
.
When an item-related event occurs, FareHarbor sends a POST
request to
the webhook URL that you have provided.
The body of this request contains a JSON representation of some of the details that will help you identify the item that was updated. For further details on what actually changed on the item, the webhook contains the external API URL and the dashboard URL.
The
external_api_url
found in the JSON can be used by interested parties to make an additional External API call to the particular item which will return the most up to date item information.The
dashboard_url
found in the JSON can be used to find out what has changed. The activity log can be used to see what has been changed and when.{ "item": { "pk": 1867, "name": "Jet Ski Tour", "company": { "name": "Hawaiian Adventures", "shortname": "hawaiianadventures", "currency": "usd" }, "external_api_url": "https://fareharbor.com/api/external/v1/companies/hawaiianadventures/items/1867", "dashboard_url": "https://fareharbor.com/hawaiianadventures/dashboard/items/1867/" } }
Contact support@fareharbor.com to have the item webhook turned on for your account.
When a crew member-related event occurs, FareHarbor sends a POST
request to
the webhook URL that you have provided.
These POST
requests will be sent for:
- crew member creations and modifications;
- crew member disabling/enabling; or
- crew member deletions.
The body of this request contains a JSON representation of the crew member, including the user information, role, and status.
{
"crew_member": {
"pk": 789,
"user": {
"name": "John Smith",
"username": "jsmith"
},
"role": {
"pk": 12,
"short_name": "captain"
},
"note": "Experienced captain with 10+ years",
"availability_id": 1234,
"status": "active"
}
}
Contact support@fareharbor.com to have the crew member webhook turned on for your account.
If you do not have your own servers, you can use third-party services that receive webhooks on your behalf.
If your webhook is functioning normally, it should always return a 200 HTTP status.
Sometimes FareHarbor sends a webhook to your server and there is a failure of one sort or another. See Question: 500s and 40x responses from webhooks for a discussion of why this might happen and how you can fix it.
If FareHarbor detects too many failures (non-200 statuses) within a short period of time, we may deactivate the webhook and contact you.
Ultimately, it is your responsibility to make sure that the webhook is working.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"booking": {
"$ref": "#/definitions/booking"
}
},
"required": ["booking"],
"additionalProperties": false,
"definitions": {
"availability": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"start_at": {
"type": "string"
},
"end_at": {
"type": "string"
},
"capacity": {
"type": "number"
},
"minimum_party_size": {
"type": ["number", "null"]
},
"maximum_party_size": {
"type": ["number", "null"]
},
"online_booking_status": {
"type": "string"
},
"headline": {
"type": "string"
},
"item": {
"$ref": "#/definitions/item"
},
"customer_type_rates": {
"type": "array",
"items": {
"$ref": "#/definitions/customer_type_rate"
}
},
"custom_field_instances": {
"type": "array",
"items": {
"$ref": "#/definitions/custom_field_instance"
}
}
},
"required": [
"pk",
"start_at",
"end_at",
"capacity",
"minimum_party_size",
"maximum_party_size",
"online_booking_status",
"headline",
"item",
"customer_type_rates",
"custom_field_instances"
],
"additionalProperties": false
},
"booking": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"uuid": {
"type": "string"
},
"availability": {
"$ref": "#/definitions/availability"
},
"company": {
"$ref": "#/definitions/company"
},
"affiliate_company": {
"$ref": "#/definitions/affiliate_company"
},
"contact": {
"$ref": "#/definitions/contact"
},
"customers": {
"type": "array",
"items": {
"$ref": "#/definitions/customer"
}
},
"invoice_price": {
"type": ["number", "null"]
},
"invoice_price_display": {
"type": ["string", "null"]
},
"display_id": {
"type": "string"
},
"external_id": {
"type": "string"
},
"order": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"display_id": {
"type": "string"
}
}
}
]
},
"status": {
"type": "string",
"enum": ["booked", "cancelled", "rebooked"]
},
"rebooked_from": {
"type": ["string", "null"]
},
"rebooked_to": {
"type": ["string", "null"]
},
"confirmation_url": {
"type": "string"
},
"receipt_subtotal": {
"type": ["number", "null"]
},
"receipt_subtotal_display": {
"type": ["string", "null"]
},
"receipt_taxes": {
"type": ["number", "null"]
},
"receipt_taxes_display": {
"type": ["string", "null"]
},
"receipt_total": {
"type": ["number", "null"]
},
"receipt_total_display": {
"type": ["string", "null"]
},
"amount_paid": {
"type": ["number", "null"]
},
"amount_paid_display": {
"type": ["string", "null"]
},
"voucher_number": {
"type": "string"
},
"custom_field_values": {
"type": "array",
"items": {
"$ref": "#/definitions/custom_field_value"
}
},
"note": {
"type": "string"
},
"note_safe_html": {
"type": "string"
},
"pickup": {
"$ref": "#/definitions/pickup"
},
"arrival": {
"$ref": "#/definitions/arrival"
},
"effective_cancellation_policy": {
"$ref": "#/definitions/effective_cancellation_policy"
},
"is_eligible_for_cancellation": {
"type": "boolean"
},
"agent": {
"$ref": "#/definitions/agent"
},
"desk": {
"$ref": "#/definitions/desk"
},
"dashboard_url": {
"type": "string"
},
"external_api_url": {
"type": "string"
},
"customer_count": {
"type": "number"
},
"is_subscribed_for_sms_updates": {
"type": "boolean"
},
"is_follow_up_email_disabled": {
"type": "boolean"
},
"is_reminder_email_disabled": {
"type": "boolean"
},
"created_at": {
"type": "string",
"format": "datetime"
},
"source_type": {
"type": "string",
"enum": ["online", "direct", "pos", "reseller", "external-api", "kiosk", "imported", "unkown"],
"example": "online"
},
"booked_by": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"required": [
"name"
],
"additionalProperties": false
}
]
}
},
"required": [
"pk",
"uuid",
"availability",
"contact",
"company",
"affiliate_company",
"customers",
"invoice_price",
"invoice_price_display",
"display_id",
"external_id",
"order",
"status",
"rebooked_from",
"rebooked_to",
"confirmation_url",
"voucher_number",
"receipt_subtotal",
"receipt_subtotal_display",
"receipt_taxes",
"receipt_taxes_display",
"receipt_total",
"receipt_total_display",
"amount_paid",
"amount_paid_display",
"custom_field_values",
"note",
"note_safe_html",
"pickup",
"arrival",
"effective_cancellation_policy",
"is_eligible_for_cancellation",
"agent",
"desk",
"dashboard_url",
"customer_count",
"is_subscribed_for_sms_updates",
"is_follow_up_email_disabled",
"is_reminder_email_disabled",
"created_at",
"source_type",
"booked_by"
],
"additionalProperties": false
},
"company": {
"type": "object",
"properties": {
"shortname": {
"type": "string"
},
"name": {
"type": "string"
},
"currency": {
"type": "string"
}
},
"required": [
"shortname",
"name",
"currency"
],
"additionalProperties": false
},
"affiliate_company": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"shortname": {
"type": "string"
},
"name": {
"type": "string"
},
"currency": {
"type": "string"
}
},
"required": [
"shortname",
"name",
"currency"
],
"additionalProperties": false
}
]
},
"contact": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"phone": {
"type": "string"
},
"phone_country": {
"type": ["string", "null"]
},
"normalized_phone": {
"type": "string"
},
"language": {
"type": "string"
},
"email": {
"type": "string"
},
"is_subscribed_for_email_updates": {
"type": "boolean"
}
},
"required": ["name", "phone", "phone_country", "normalized_phone", "email", "is_subscribed_for_email_updates"],
"additionalProperties": false
},
"customer": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"checkin_url": {
"type": "string"
},
"checkin_status": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/definitions/checkin_status"
}
]
},
"invoice_cost": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"feeable": {
"type": "number"
},
"price": {
"type": ["number", "null"]
},
"tax": {
"type": "number"
},
"tax_by_type": {
"type": "object"
},
"taxable": {
"type": "number"
},
"total": {
"type": "number"
}
}
}
]
},
"total_cost": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"feeable": {
"type": "number"
},
"price": {
"type": ["number", "null"]
},
"tax": {
"type": "number"
},
"tax_by_type": {
"type": "object"
},
"taxable": {
"type": "number"
},
"total": {
"type": "number"
}
}
}
]
},
"customer_type_rate": {
"$ref": "#/definitions/customer_type_rate"
},
"custom_field_values": {
"type": "array",
"items": {
"$ref": "#/definitions/custom_field_value"
}
}
},
"required": ["pk", "checkin_url", "customer_type_rate", "custom_field_values"],
"additionalProperties": false
},
"checkin_status": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"name": {
"type": "string"
},
"type": {
"type": "string"
}
},
"required": ["pk", "name", "type"],
"additionalProperties": false
},
"customer_type": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"singular": {
"type": "string"
},
"plural": {
"type": "string"
},
"note": {
"type": "string"
}
},
"required": ["pk", "singular", "plural"],
"additionalProperties": false
},
"customer_prototype": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"display_name": {
"type": "string"
},
"note": {
"type": "string"
},
"total": {
"type": "number"
},
"total_including_tax": {
"type": "number"
}
},
"required": ["pk", "display_name", "note", "total"],
"additionalProperties": false
},
"customer_type_rate": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"total": {
"type": "number"
},
"total_including_tax": {
"type": "number"
},
"capacity": {
"type": ["number", "null"]
},
"minimum_party_size": {
"type": ["number", "null"]
},
"maximum_party_size": {
"type": ["number", "null"]
},
"customer_type": {
"$ref": "#/definitions/customer_type"
},
"customer_prototype": {
"$ref": "#/definitions/customer_prototype"
},
"custom_field_instances": {
"type": "array",
"items": {
"$ref": "#/definitions/custom_field_instance"
}
}
},
"required": [
"pk",
"total",
"capacity",
"minimum_party_size",
"maximum_party_size",
"customer_type",
"customer_prototype"
],
"additionalProperties": false
},
"custom_field": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"type": {
"type": "string",
"enum": ["yes-no", "short", "long", "extended-option", "count", "multi-campaign"]
},
"is_required": {
"type": "boolean"
},
"description": {
"type": "string"
},
"description_safe_html": {
"type": "string"
},
"name": {
"type": "string"
},
"title": {
"type": "string"
},
"booking_notes": {
"type": "string"
},
"booking_notes_safe_html": {
"type": "string"
},
"modifier_kind": {
"type": "string"
},
"modifier_type": {
"type": "string"
},
"offset": {
"type": "number"
},
"percentage": {
"type": "number"
},
"is_always_per_customer": {
"type": "boolean"
},
"is_taxable": {
"type": "boolean"
},
"extended_options": {
"type": "array",
"items": {
"$ref": "#/definitions/extended_option"
}
}
},
"required": [
"pk",
"type",
"is_required",
"description",
"description_safe_html",
"name",
"booking_notes",
"booking_notes_safe_html",
"offset"
],
"additionalProperties": false
},
"custom_field_instance": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"custom_field": {
"$ref": "#/definitions/custom_field"
}
},
"required": ["pk", "custom_field"],
"additionalProperties": false
},
"custom_field_value": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"custom_field": {
"$ref": "#/definitions/custom_field"
},
"name": {
"type": "string"
},
"value": {
"type": "string",
"maxLength": 2048
},
"display_value": {
"type": "string",
"maxLength": 2048
}
},
"required": ["pk", "custom_field", "name", "value", "display_value"],
"additionalProperties": false
},
"extended_option": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"description_safe_html": {
"type": "string"
},
"modifier_kind": {
"type": "string"
},
"modifier_type": {
"type": "string"
},
"offset": {
"type": "number"
},
"percentage": {
"type": "number"
},
"is_always_per_customer": {
"type": "boolean"
},
"is_taxable": {
"type": "boolean"
}
},
"required": [
"pk",
"name",
"description",
"description_safe_html",
"modifier_kind",
"modifier_type",
"offset",
"percentage",
"is_always_per_customer",
"is_taxable"
],
"additionalProperties": false
},
"item": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"name": {
"type": "string"
},
"headline": {
"type": "string"
},
"primary_location": {
"oneOf": [
{
"$ref": "#/definitions/primary_location"
},
{
"type": "null"
}
]
}
},
"required": ["pk", "name", "headline", "primary_location"],
"additionalProperties": false
},
"pickup": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"time": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"description_safe_html": {
"type": "string"
},
"map_url": {
"type": "string"
},
"display_text": {
"type": "string"
}
},
"required": [
"time",
"name",
"description",
"description_safe_html",
"map_url",
"display_text"
],
"additionalProperties": false
}
]
},
"arrival": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"time": {
"type": "string"
},
"notes": {
"type": "string"
},
"notes_safe_html": {
"type": "string"
},
"display_text": {
"type": "string"
}
},
"required": [
"time",
"notes",
"notes_safe_html",
"display_text"
],
"additionalProperties": false
}
]
},
"effective_cancellation_policy": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"cutoff": {
"oneOf": [
{
"type": "string"
},
{
"type": "null"
}
]
}
},
"required": [
"type",
"cutoff"
],
"additionalProperties": false
},
"agent": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"name": {
"type": "string"
}
},
"required": [
"pk",
"name"
],
"additionalProperties": false
}
]
},
"desk": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"name": {
"type": "string"
}
},
"required": [
"pk",
"name"
],
"additionalProperties": false
}
]
},
"primary_location": {
"type": "object",
"properties": {
"pk": {
"type": "number",
"format": "int32",
"description": "The location's unique ID.",
"example": 234234
},
"type": {
"type": "string",
"description": "The location's type.",
"example": "primary"
},
"note": {
"type": "string",
"format": "markdown",
"description": "A brief note about this location that can be displayed to end users.",
"example": "Next to the blue fence."
},
"note_safe_html": {
"type": "string",
"format": "markdown",
"description": "A brief note about this location that can be displayed to end users.",
"example": "<p>Next to the blue fence.</p>"
},
"address": {
"$ref": "#/definitions/address",
"description": "The location's physical address."
},
"longitude": {
"oneOf": [
{
"type": "number",
"example": 21.30
},
{
"type": "null"
}
],
"description": "The location's longitude."
},
"latitude": {
"oneOf": [
{
"type": "number",
"example": -157.85
},
{
"type": "null"
}
],
"description": "The location's latitude."
},
"google_place_id": {
"type": "string",
"format": "uuid",
"description": "The location's Google Place ID.",
"example": "ChIJYZ4srGUSAHwRT1Da4amp3x"
},
"tripadvisor_url": {
"type": "string",
"format": "uri",
"description": "The location's TripAdvisor URL.",
"example": "https://www.tripadvisor.com/Attraction_Review-g60982-d184886-Reviews-Epic_Jet_Ski_Tour-Honolulu_Oahu_Hawaii.html"
}
},
"required": [
"pk",
"type",
"note",
"note_safe_html",
"address",
"longitude",
"latitude",
"google_place_id",
"tripadvisor_url"
],
"additionalProperties": false
},
"address": {
"type": "object",
"properties": {
"city": {
"type": "string",
"example": "Honolulu"
},
"country": {
"type": "string",
"example": "US"
},
"postal_code": {
"type": "string",
"example": "96821"
},
"province": {
"type": "string",
"example": "HI"
},
"street": {
"type": "string",
"example": "123 Wailupe Cir"
}
},
"required": [
"city",
"country",
"postal_code",
"province",
"street"
],
"additionalProperties": false
},
"waiver_signatures": {
"type": "object",
"properties": {
"fareharbor": {
"$ref": "#/definitions/fh_waiver_signatures"
}
},
"additionalProperties": false
},
"fh_waiver_signatures": {
"type": "array",
"items": {
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email",
"example": "johnsmith@example.com"
},
"first_name": {
"type": "string",
"example": "John"
},
"last_name": {
"type": "string",
"example": "Smith"
},
"is_marketing_allowed": {
"type": "boolean",
"description": "Whether the person signing the waiver has opted in for marketing communications.",
"example": true
},
"is_customer_parent": {
"type": "boolean",
"description": "Indicating if the signature has any related minor records.",
"example": false
},
"dob": {
"type": ["string", "null"],
"example": "1991-01-05"
},
"phone_number": {
"type": ["string", "null"],
"example": "+16468109900"
},
"address_line": {
"type": ["string", "null"],
"example": "7824 15th Ave"
},
"city": {
"type": ["string", "null"],
"example": "Brooklyn"
},
"state_province": {
"type": ["string", "null"],
"example": "NY"
},
"postcode": {
"type": ["string", "null"],
"example": "11228"
},
"country": {
"type": ["string", "null"],
"example": "US"
}
},
"required": [
"email",
"first_name",
"last_name",
"is_marketing_allowed",
"is_customer_parent",
"dob",
"phone_number",
"address_line",
"city",
"state_province",
"postcode",
"country"
],
"additionalProperties": false
},
"description": "A list of FareHarbor waivers signatures with details."
}
}
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"booking": {
"$ref": "#/definitions/booking"
}
},
"required": ["booking"],
"additionalProperties": false,
"definitions": {
"availability": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"start_at": {
"type": "string"
},
"end_at": {
"type": "string"
},
"capacity": {
"type": "number"
},
"minimum_party_size": {
"type": ["number", "null"]
},
"maximum_party_size": {
"type": ["number", "null"]
},
"online_booking_status": {
"type": "string"
},
"headline": {
"type": "string"
},
"item": {
"$ref": "#/definitions/item"
},
"customer_type_rates": {
"type": "array",
"items": {
"$ref": "#/definitions/customer_type_rate"
}
},
"custom_field_instances": {
"type": "array",
"items": {
"$ref": "#/definitions/custom_field_instance"
}
}
},
"required": [
"pk",
"start_at",
"end_at",
"capacity",
"minimum_party_size",
"maximum_party_size",
"online_booking_status",
"headline",
"item",
"customer_type_rates",
"custom_field_instances"
],
"additionalProperties": false
},
"booking": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"uuid": {
"type": "string"
},
"availability": {
"$ref": "#/definitions/availability"
},
"company": {
"$ref": "#/definitions/company"
},
"affiliate_company": {
"$ref": "#/definitions/affiliate_company"
},
"contact": {
"$ref": "#/definitions/contact"
},
"customers": {
"type": "array",
"items": {
"$ref": "#/definitions/customer"
}
},
"invoice_price": {
"type": ["number", "null"]
},
"invoice_price_display": {
"type": ["string", "null"]
},
"display_id": {
"type": "string"
},
"external_id": {
"type": "string"
},
"order": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"display_id": {
"type": "string"
}
}
}
]
},
"status": {
"type": "string",
"enum": ["booked", "cancelled", "rebooked"]
},
"rebooked_from": {
"type": ["string", "null"]
},
"rebooked_to": {
"type": ["string", "null"]
},
"confirmation_url": {
"type": "string"
},
"receipt_subtotal": {
"type": ["number", "null"]
},
"receipt_subtotal_display": {
"type": ["string", "null"]
},
"receipt_taxes": {
"type": ["number", "null"]
},
"receipt_taxes_display": {
"type": ["string", "null"]
},
"receipt_total": {
"type": ["number", "null"]
},
"receipt_total_display": {
"type": ["string", "null"]
},
"amount_paid": {
"type": ["number", "null"]
},
"amount_paid_display": {
"type": ["string", "null"]
},
"voucher_number": {
"type": "string"
},
"custom_field_values": {
"type": "array",
"items": {
"$ref": "#/definitions/custom_field_value"
}
},
"note": {
"type": "string"
},
"note_safe_html": {
"type": "string"
},
"pickup": {
"$ref": "#/definitions/pickup"
},
"arrival": {
"$ref": "#/definitions/arrival"
},
"effective_cancellation_policy": {
"$ref": "#/definitions/effective_cancellation_policy"
},
"is_eligible_for_cancellation": {
"type": "boolean"
},
"agent": {
"$ref": "#/definitions/agent"
},
"desk": {
"$ref": "#/definitions/desk"
},
"payments": {
"type": "array",
"items": {
"$ref": "#/definitions/payment"
}
},
"dashboard_url": {
"type": "string"
},
"external_api_url": {
"type": "string"
},
"customer_count": {
"type": "number"
},
"is_subscribed_for_sms_updates": {
"type": "boolean"
},
"is_follow_up_email_disabled": {
"type": "boolean"
},
"is_reminder_email_disabled": {
"type": "boolean"
},
"created_at": {
"type": "string",
"format": "datetime"
},
"source_type": {
"type": "string",
"enum": ["online", "direct", "pos", "reseller", "external-api", "kiosk", "imported", "unkown"],
"example": "online"
},
"booked_by": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"required": [
"name"
],
"additionalProperties": false
}
]
}
},
"required": [
"pk",
"uuid",
"availability",
"contact",
"company",
"affiliate_company",
"customers",
"invoice_price",
"invoice_price_display",
"display_id",
"external_id",
"order",
"status",
"rebooked_from",
"rebooked_to",
"confirmation_url",
"voucher_number",
"receipt_subtotal",
"receipt_subtotal_display",
"receipt_taxes",
"receipt_taxes_display",
"receipt_total",
"receipt_total_display",
"amount_paid",
"amount_paid_display",
"custom_field_values",
"note",
"note_safe_html",
"pickup",
"arrival",
"effective_cancellation_policy",
"is_eligible_for_cancellation",
"agent",
"desk",
"payments",
"dashboard_url",
"customer_count",
"is_subscribed_for_sms_updates",
"is_follow_up_email_disabled",
"is_reminder_email_disabled",
"created_at",
"source_type",
"booked_by"
],
"additionalProperties": false
},
"company": {
"type": "object",
"properties": {
"shortname": {
"type": "string"
},
"name": {
"type": "string"
},
"currency": {
"type": "string"
}
},
"required": [
"shortname",
"name",
"currency"
],
"additionalProperties": false
},
"affiliate_company": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"shortname": {
"type": "string"
},
"name": {
"type": "string"
},
"currency": {
"type": "string"
}
},
"required": [
"shortname",
"name",
"currency"
],
"additionalProperties": false
}
]
},
"contact": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"phone": {
"type": "string"
},
"phone_country": {
"type": ["string", "null"]
},
"normalized_phone": {
"type": "string"
},
"language": {
"type": "string"
},
"email": {
"type": "string"
},
"is_subscribed_for_email_updates": {
"type": "boolean"
}
},
"required": ["name", "phone", "phone_country", "normalized_phone", "email", "is_subscribed_for_email_updates"],
"additionalProperties": false
},
"customer": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"checkin_url": {
"type": "string"
},
"checkin_status": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/definitions/checkin_status"
}
]
},
"invoice_cost": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"feeable": {
"type": "number"
},
"price": {
"type": ["number", "null"]
},
"tax": {
"type": "number"
},
"tax_by_type": {
"type": "object"
},
"taxable": {
"type": "number"
},
"total": {
"type": "number"
}
}
}
]
},
"total_cost": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"feeable": {
"type": "number"
},
"price": {
"type": ["number", "null"]
},
"tax": {
"type": "number"
},
"tax_by_type": {
"type": "object"
},
"taxable": {
"type": "number"
},
"total": {
"type": "number"
}
}
}
]
},
"customer_type_rate": {
"$ref": "#/definitions/customer_type_rate"
},
"custom_field_values": {
"type": "array",
"items": {
"$ref": "#/definitions/custom_field_value"
}
}
},
"required": ["pk", "checkin_url", "customer_type_rate", "custom_field_values"],
"additionalProperties": false
},
"checkin_status": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"name": {
"type": "string"
},
"type": {
"type": "string"
}
},
"required": ["pk", "name", "type"],
"additionalProperties": false
},
"customer_type": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"singular": {
"type": "string"
},
"plural": {
"type": "string"
},
"note": {
"type": "string"
}
},
"required": ["pk", "singular", "plural"],
"additionalProperties": false
},
"customer_prototype": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"display_name": {
"type": "string"
},
"note": {
"type": "string"
},
"total": {
"type": "number"
},
"total_including_tax": {
"type": "number"
}
},
"required": ["pk", "display_name", "note", "total"],
"additionalProperties": false
},
"customer_type_rate": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"total": {
"type": "number"
},
"total_including_tax": {
"type": "number"
},
"capacity": {
"type": ["number", "null"]
},
"minimum_party_size": {
"type": ["number", "null"]
},
"maximum_party_size": {
"type": ["number", "null"]
},
"customer_type": {
"$ref": "#/definitions/customer_type"
},
"customer_prototype": {
"$ref": "#/definitions/customer_prototype"
},
"custom_field_instances": {
"type": "array",
"items": {
"$ref": "#/definitions/custom_field_instance"
}
}
},
"required": [
"pk",
"total",
"capacity",
"minimum_party_size",
"maximum_party_size",
"customer_type",
"customer_prototype"
],
"additionalProperties": false
},
"custom_field": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"type": {
"type": "string",
"enum": ["yes-no", "short", "long", "extended-option", "count", "multi-campaign"]
},
"is_required": {
"type": "boolean"
},
"description": {
"type": "string"
},
"description_safe_html": {
"type": "string"
},
"name": {
"type": "string"
},
"title": {
"type": "string"
},
"booking_notes": {
"type": "string"
},
"booking_notes_safe_html": {
"type": "string"
},
"modifier_kind": {
"type": "string"
},
"modifier_type": {
"type": "string"
},
"offset": {
"type": "number"
},
"percentage": {
"type": "number"
},
"is_always_per_customer": {
"type": "boolean"
},
"is_taxable": {
"type": "boolean"
},
"extended_options": {
"type": "array",
"items": {
"$ref": "#/definitions/extended_option"
}
}
},
"required": [
"pk",
"type",
"is_required",
"description",
"description_safe_html",
"name",
"booking_notes",
"booking_notes_safe_html",
"offset"
],
"additionalProperties": false
},
"custom_field_instance": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"custom_field": {
"$ref": "#/definitions/custom_field"
}
},
"required": ["pk", "custom_field"],
"additionalProperties": false
},
"custom_field_value": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"custom_field": {
"$ref": "#/definitions/custom_field"
},
"name": {
"type": "string"
},
"value": {
"type": "string",
"maxLength": 2048
},
"display_value": {
"type": "string",
"maxLength": 2048
}
},
"required": ["pk", "custom_field", "name", "value", "display_value"],
"additionalProperties": false
},
"extended_option": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"description_safe_html": {
"type": "string"
},
"modifier_kind": {
"type": "string"
},
"modifier_type": {
"type": "string"
},
"offset": {
"type": "number"
},
"percentage": {
"type": "number"
},
"is_always_per_customer": {
"type": "boolean"
},
"is_taxable": {
"type": "boolean"
}
},
"required": [
"pk",
"name",
"description",
"description_safe_html",
"modifier_kind",
"modifier_type",
"offset",
"percentage",
"is_always_per_customer",
"is_taxable"
],
"additionalProperties": false
},
"item": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"name": {
"type": "string"
},
"headline": {
"type": "string"
},
"primary_location": {
"oneOf": [
{
"$ref": "#/definitions/primary_location"
},
{
"type": "null"
}
]
}
},
"required": ["pk", "name", "headline", "primary_location"],
"additionalProperties": false
},
"pickup": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"time": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"description_safe_html": {
"type": "string"
},
"map_url": {
"type": "string"
},
"display_text": {
"type": "string"
}
},
"required": [
"time",
"name",
"description",
"description_safe_html",
"map_url",
"display_text"
],
"additionalProperties": false
}
]
},
"arrival": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"time": {
"type": "string"
},
"notes": {
"type": "string"
},
"notes_safe_html": {
"type": "string"
},
"display_text": {
"type": "string"
}
},
"required": [
"time",
"notes",
"notes_safe_html",
"display_text"
],
"additionalProperties": false
}
]
},
"effective_cancellation_policy": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"cutoff": {
"oneOf": [
{
"type": "string"
},
{
"type": "null"
}
]
}
},
"required": [
"type",
"cutoff"
],
"additionalProperties": false
},
"agent": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"name": {
"type": "string"
}
},
"required": [
"pk",
"name"
],
"additionalProperties": false
}
]
},
"desk": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"name": {
"type": "string"
}
},
"required": [
"pk",
"name"
],
"additionalProperties": false
}
]
},
"payment": {
"type": "object",
"properties": {
"amount_paid": {
"type": ["number", "null"]
},
"amount_paid_display": {
"type": ["string", "null"]
},
"created_at": {
"type": "string",
"maxLength": 2048
},
"currency": {
"type": "string",
"maxLength": 3
},
"initial_amount_paid": {
"type": ["number", "null"]
},
"initial_amount_paid_display": {
"type": ["string", "null"]
},
"pk": {
"type": "number"
},
"refunds": {
"type": "array",
"items": {
"$ref": "#/definitions/refund"
}
},
"type": {
"type": "string",
"maxLength": 2048
},
"in_store_payment_type": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"name": {
"type": "string",
"maxLength": 128
}
},
"required": [
"pk",
"name"
]
}
]
},
"status": {
"type": "string",
"maxLength": 2048
}
},
"required": [
"amount_paid",
"amount_paid_display",
"created_at",
"currency",
"initial_amount_paid",
"initial_amount_paid_display",
"pk",
"refunds",
"type",
"in_store_payment_type",
"status"
],
"additionalProperties": false
},
"refund": {
"type": "object",
"properties": {
"amount_refunded": {
"type": ["number", "null"]
},
"amount_refunded_display": {
"type": ["string", "null"]
},
"created_at": {
"type": "string",
"maxLength": 2048
},
"is_cancelled": {
"type": "boolean"
},
"pk": {
"type": "number"
}
},
"required": ["amount_refunded", "amount_refunded_display", "created_at", "pk"],
"additionalProperties": false
},
"primary_location": {
"type": "object",
"properties": {
"pk": {
"type": "number",
"format": "int32",
"description": "The location's unique ID.",
"example": 234234
},
"type": {
"type": "string",
"description": "The location's type.",
"example": "primary"
},
"note": {
"type": "string",
"format": "markdown",
"description": "A brief note about this location that can be displayed to end users.",
"example": "Next to the blue fence."
},
"note_safe_html": {
"type": "string",
"format": "markdown",
"description": "A brief note about this location that can be displayed to end users.",
"example": "<p>Next to the blue fence.</p>"
},
"address": {
"$ref": "#/definitions/address",
"description": "The location's physical address."
},
"longitude": {
"oneOf": [
{
"type": "number",
"example": 21.3069
},
{
"type": "null"
}
],
"description": "The location's longitude."
},
"latitude": {
"oneOf": [
{
"type": "number",
"example": -157.8583
},
{
"type": "null"
}
],
"description": "The location's latitude."
},
"google_place_id": {
"type": "string",
"format": "uuid",
"description": "The location's Google Place ID.",
"example": "ChIJYZ4srGUSAHwRT1Da4amp3x"
},
"tripadvisor_url": {
"type": "string",
"format": "uri",
"description": "The location's TripAdvisor URL.",
"example": "https://www.tripadvisor.com/Attraction_Review-g60982-d184886-Reviews-Epic_Jet_Ski_Tour-Honolulu_Oahu_Hawaii.html"
}
},
"required": [
"pk",
"type",
"note",
"note_safe_html",
"address",
"longitude",
"latitude",
"google_place_id",
"tripadvisor_url"
],
"additionalProperties": false
},
"address": {
"type": "object",
"properties": {
"city": {
"type": "string",
"example": "Honolulu"
},
"country": {
"type": "string",
"example": "US"
},
"postal_code": {
"type": "string",
"example": "96821"
},
"province": {
"type": "string",
"example": "HI"
},
"street": {
"type": "string",
"example": "123 Wailupe Cir"
}
},
"required": [
"city",
"country",
"postal_code",
"province",
"street"
],
"additionalProperties": false
},
"waiver_signatures": {
"type": "object",
"properties": {
"fareharbor": {
"$ref": "#/definitions/fh_waiver_signatures"
}
},
"additionalProperties": false
},
"fh_waiver_signatures": {
"type": "array",
"items": {
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email",
"example": "johnsmith@example.com"
},
"first_name": {
"type": "string",
"example": "John"
},
"last_name": {
"type": "string",
"example": "Smith"
},
"is_marketing_allowed": {
"type": "boolean",
"description": "Whether the person signing the waiver has opted in for marketing communications.",
"example": true
},
"is_customer_parent": {
"type": "boolean",
"description": "Indicating if the signature has any related minor records.",
"example": false
},
"dob": {
"type": ["string", "null"],
"example": "1991-01-05"
},
"phone_number": {
"type": ["string", "null"],
"example": "+16468109900"
},
"address_line": {
"type": ["string", "null"],
"example": "7824 15th Ave"
},
"city": {
"type": ["string", "null"],
"example": "Brooklyn"
},
"state_province": {
"type": ["string", "null"],
"example": "NY"
},
"postcode": {
"type": ["string", "null"],
"example": "11228"
},
"country": {
"type": ["string", "null"],
"example": "US"
}
},
"required": [
"email",
"first_name",
"last_name",
"is_marketing_allowed",
"is_customer_parent",
"dob",
"phone_number",
"address_line",
"city",
"state_province",
"postcode",
"country"
],
"additionalProperties": false
},
"description": "A list of FareHarbor waivers signatures with details."
}
}
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"booking": {
"$ref": "#/definitions/booking"
}
},
"required": ["booking"],
"additionalProperties": false,
"definitions": {
"availability": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"item": {
"$ref": "#/definitions/item"
},
"start_at": {
"type": "string"
},
"end_at": {
"type": "string"
}
},
"required": [
"pk",
"item",
"start_at",
"end_at"
],
"additionalProperties": false
},
"booking": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"uuid": {
"type": "string"
},
"availability": {
"$ref": "#/definitions/availability"
},
"company": {
"$ref": "#/definitions/company"
},
"affiliate_company": {
"$ref": "#/definitions/affiliate_company"
},
"contact": {
"$ref": "#/definitions/contact"
},
"customers": {
"type": "array",
"items": {
"$ref": "#/definitions/customer"
}
},
"invoice_price": {
"type": ["number", "null"]
},
"invoice_price_display": {
"type": ["string", "null"]
},
"display_id": {
"type": "string"
},
"external_id": {
"type": "string"
},
"order": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"display_id": {
"type": "string"
}
}
}
]
},
"status": {
"type": "string",
"enum": ["booked", "cancelled", "rebooked"]
},
"rebooked_from": {
"type": ["string", "null"]
},
"rebooked_to": {
"type": ["string", "null"]
},
"confirmation_url": {
"type": "string"
},
"receipt_subtotal": {
"type": ["number", "null"]
},
"receipt_subtotal_display": {
"type": ["string", "null"]
},
"receipt_taxes": {
"type": ["number", "null"]
},
"receipt_taxes_display": {
"type": ["string", "null"]
},
"receipt_total": {
"type": ["number", "null"]
},
"receipt_total_display": {
"type": ["string", "null"]
},
"amount_paid": {
"type": ["number", "null"]
},
"amount_paid_display": {
"type": ["string", "null"]
},
"voucher_number": {
"type": "string"
},
"custom_field_values": {
"type": "array",
"items": {
"$ref": "#/definitions/custom_field_value"
}
},
"note": {
"type": "string"
},
"note_safe_html": {
"type": "string"
},
"pickup": {
"$ref": "#/definitions/pickup"
},
"arrival": {
"$ref": "#/definitions/arrival"
},
"effective_cancellation_policy": {
"$ref": "#/definitions/effective_cancellation_policy"
},
"is_eligible_for_cancellation": {
"type": "boolean"
},
"agent": {
"$ref": "#/definitions/agent"
},
"desk": {
"$ref": "#/definitions/desk"
},
"dashboard_url": {
"type": "string"
},
"external_api_url": {
"type": "string"
},
"customer_count": {
"type": "number"
},
"is_subscribed_for_sms_updates": {
"type": "boolean"
},
"is_follow_up_email_disabled": {
"type": "boolean"
},
"is_reminder_email_disabled": {
"type": "boolean"
},
"created_at": {
"type": "string",
"format": "datetime"
},
"source_type": {
"type": "string",
"enum": ["online", "direct", "pos", "reseller", "external-api", "kiosk", "imported", "unkown"],
"example": "online"
},
"booked_by": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"required": [
"name"
],
"additionalProperties": false
}
]
}
},
"required": [
"pk",
"uuid",
"availability",
"contact",
"company",
"affiliate_company",
"customers",
"invoice_price",
"invoice_price_display",
"display_id",
"external_id",
"order",
"status",
"rebooked_from",
"rebooked_to",
"confirmation_url",
"voucher_number",
"receipt_subtotal",
"receipt_subtotal_display",
"receipt_taxes",
"receipt_taxes_display",
"receipt_total",
"receipt_total_display",
"amount_paid",
"amount_paid_display",
"custom_field_values",
"note",
"note_safe_html",
"pickup",
"arrival",
"effective_cancellation_policy",
"is_eligible_for_cancellation",
"agent",
"desk",
"dashboard_url",
"customer_count",
"is_subscribed_for_sms_updates",
"is_follow_up_email_disabled",
"is_reminder_email_disabled",
"created_at",
"source_type",
"booked_by"
],
"additionalProperties": false
},
"company": {
"type": "object",
"properties": {
"shortname": {
"type": "string"
},
"name": {
"type": "string"
},
"currency": {
"type": "string"
}
},
"required": [
"shortname",
"name",
"currency"
],
"additionalProperties": false
},
"affiliate_company": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"shortname": {
"type": "string"
},
"name": {
"type": "string"
},
"currency": {
"type": "string"
}
},
"required": [
"shortname",
"name",
"currency"
],
"additionalProperties": false
}
]
},
"contact": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"phone": {
"type": "string"
},
"phone_country": {
"type": ["string", "null"]
},
"normalized_phone": {
"type": "string"
},
"language": {
"type": "string"
},
"email": {
"type": "string"
},
"is_subscribed_for_email_updates": {
"type": "boolean"
}
},
"required": ["name", "phone", "phone_country", "normalized_phone", "email", "is_subscribed_for_email_updates"],
"additionalProperties": false
},
"customer": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"checkin_url": {
"type": "string"
},
"checkin_status": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/definitions/checkin_status"
}
]
},
"invoice_cost": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"feeable": {
"type": "number"
},
"price": {
"type": ["number", "null"]
},
"tax": {
"type": "number"
},
"tax_by_type": {
"type": "object"
},
"taxable": {
"type": "number"
},
"total": {
"type": "number"
}
}
}
]
},
"total_cost": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"feeable": {
"type": "number"
},
"price": {
"type": ["number", "null"]
},
"tax": {
"type": "number"
},
"tax_by_type": {
"type": "object"
},
"taxable": {
"type": "number"
},
"total": {
"type": "number"
}
}
}
]
},
"customer_type_rate": {
"$ref": "#/definitions/customer_type_rate"
},
"custom_field_values": {
"type": "array",
"items": {
"$ref": "#/definitions/custom_field_value"
}
}
},
"required": ["pk", "checkin_url", "customer_type_rate", "custom_field_values"],
"additionalProperties": false
},
"checkin_status": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"name": {
"type": "string"
},
"type": {
"type": "string"
}
},
"required": ["pk", "name", "type"],
"additionalProperties": false
},
"customer_type": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"singular": {
"type": "string"
},
"plural": {
"type": "string"
}
},
"required": ["pk", "singular", "plural"],
"additionalProperties": false
},
"customer_prototype": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"display_name": {
"type": "string"
}
},
"required": ["pk", "display_name"],
"additionalProperties": false
},
"customer_type_rate": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"customer_type": {
"$ref": "#/definitions/customer_type"
},
"customer_prototype": {
"$ref": "#/definitions/customer_prototype"
}
},
"required": [
"pk",
"customer_type",
"customer_prototype"
],
"additionalProperties": false
},
"custom_field": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"type": {
"type": "string",
"enum": ["yes-no", "short", "long", "extended-option", "count", "multi-campaign"]
},
"is_required": {
"type": "boolean"
},
"description": {
"type": "string"
},
"description_safe_html": {
"type": "string"
},
"name": {
"type": "string"
},
"title": {
"type": "string"
},
"booking_notes": {
"type": "string"
},
"booking_notes_safe_html": {
"type": "string"
},
"modifier_kind": {
"type": "string"
},
"modifier_type": {
"type": "string"
},
"offset": {
"type": "number"
},
"percentage": {
"type": "number"
},
"is_always_per_customer": {
"type": "boolean"
},
"is_taxable": {
"type": "boolean"
}
},
"required": [
"pk",
"type",
"is_required",
"description",
"description_safe_html",
"name",
"booking_notes",
"booking_notes_safe_html",
"offset"
],
"additionalProperties": false
},
"custom_field_instance": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"custom_field": {
"$ref": "#/definitions/custom_field"
}
},
"required": ["pk", "custom_field"],
"additionalProperties": false
},
"custom_field_value": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"custom_field": {
"$ref": "#/definitions/custom_field"
},
"name": {
"type": "string"
},
"value": {
"type": "string",
"maxLength": 2048
},
"display_value": {
"type": "string",
"maxLength": 2048
}
},
"required": ["pk", "custom_field", "name", "value", "display_value"],
"additionalProperties": false
},
"item": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"name": {
"type": "string"
}
},
"required": ["pk", "name"],
"additionalProperties": false
},
"pickup": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"time": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"description_safe_html": {
"type": "string"
},
"map_url": {
"type": "string"
},
"display_text": {
"type": "string"
}
},
"required": [
"time",
"name",
"description",
"description_safe_html",
"map_url",
"display_text"
],
"additionalProperties": false
}
]
},
"arrival": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"time": {
"type": "string"
},
"notes": {
"type": "string"
},
"notes_safe_html": {
"type": "string"
},
"display_text": {
"type": "string"
}
},
"required": [
"time",
"notes",
"notes_safe_html",
"display_text"
],
"additionalProperties": false
}
]
},
"effective_cancellation_policy": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"cutoff": {
"oneOf": [
{
"type": "string"
},
{
"type": "null"
}
]
}
},
"required": [
"type",
"cutoff"
],
"additionalProperties": false
},
"agent": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"name": {
"type": "string"
}
},
"required": [
"pk",
"name"
],
"additionalProperties": false
}
]
},
"desk": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"name": {
"type": "string"
}
},
"required": [
"pk",
"name"
],
"additionalProperties": false
}
]
},
"waiver_signatures": {
"type": "object",
"properties": {
"fareharbor": {
"$ref": "#/definitions/fh_waiver_signatures"
}
},
"additionalProperties": false
},
"fh_waiver_signatures": {
"type": "array",
"items": {
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email",
"example": "johnsmith@example.com"
},
"first_name": {
"type": "string",
"example": "John"
},
"last_name": {
"type": "string",
"example": "Smith"
},
"is_marketing_allowed": {
"type": "boolean",
"description": "Whether the person signing the waiver has opted in for marketing communications.",
"example": true
},
"is_customer_parent": {
"type": "boolean",
"description": "Indicating if the signature has any related minor records.",
"example": false
},
"dob": {
"type": ["string", "null"],
"example": "1991-01-05"
},
"phone_number": {
"type": ["string", "null"],
"example": "+16468109900"
},
"address_line": {
"type": ["string", "null"],
"example": "7824 15th Ave"
},
"city": {
"type": ["string", "null"],
"example": "Brooklyn"
},
"state_province": {
"type": ["string", "null"],
"example": "NY"
},
"postcode": {
"type": ["string", "null"],
"example": "11228"
},
"country": {
"type": ["string", "null"],
"example": "US"
}
},
"required": [
"email",
"first_name",
"last_name",
"is_marketing_allowed",
"is_customer_parent",
"dob",
"phone_number",
"address_line",
"city",
"state_province",
"postcode",
"country"
],
"additionalProperties": false
},
"description": "A list of FareHarbor waivers signatures with details."
}
}
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"booking": {
"$ref": "#/definitions/booking"
}
},
"required": ["booking"],
"additionalProperties": false,
"definitions": {
"availability": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"item": {
"$ref": "#/definitions/item"
},
"start_at": {
"type": "string"
},
"end_at": {
"type": "string"
}
},
"required": [
"pk",
"item",
"start_at",
"end_at"
],
"additionalProperties": false
},
"booking": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"uuid": {
"type": "string"
},
"availability": {
"$ref": "#/definitions/availability"
},
"company": {
"$ref": "#/definitions/company"
},
"affiliate_company": {
"$ref": "#/definitions/affiliate_company"
},
"contact": {
"$ref": "#/definitions/contact"
},
"customers": {
"type": "array",
"items": {
"$ref": "#/definitions/customer"
}
},
"invoice_price": {
"type": ["number", "null"]
},
"invoice_price_display": {
"type": ["string", "null"]
},
"display_id": {
"type": "string"
},
"external_id": {
"type": "string"
},
"order": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"display_id": {
"type": "string"
}
}
}
]
},
"status": {
"type": "string",
"enum": ["booked", "cancelled", "rebooked"]
},
"rebooked_from": {
"type": ["string", "null"]
},
"rebooked_to": {
"type": ["string", "null"]
},
"confirmation_url": {
"type": "string"
},
"receipt_subtotal": {
"type": ["number", "null"]
},
"receipt_subtotal_display": {
"type": ["string", "null"]
},
"receipt_taxes": {
"type": ["number", "null"]
},
"receipt_taxes_display": {
"type": ["string", "null"]
},
"receipt_total": {
"type": ["number", "null"]
},
"receipt_total_display": {
"type": ["string", "null"]
},
"amount_paid": {
"type": ["number", "null"]
},
"amount_paid_display": {
"type": ["string", "null"]
},
"voucher_number": {
"type": "string"
},
"custom_field_values": {
"type": "array",
"items": {
"$ref": "#/definitions/custom_field_value"
}
},
"note": {
"type": "string"
},
"note_safe_html": {
"type": "string"
},
"pickup": {
"$ref": "#/definitions/pickup"
},
"arrival": {
"$ref": "#/definitions/arrival"
},
"effective_cancellation_policy": {
"$ref": "#/definitions/effective_cancellation_policy"
},
"is_eligible_for_cancellation": {
"type": "boolean"
},
"agent": {
"$ref": "#/definitions/agent"
},
"desk": {
"$ref": "#/definitions/desk"
},
"payments": {
"type": "array",
"items": {
"$ref": "#/definitions/payment"
}
},
"dashboard_url": {
"type": "string"
},
"external_api_url": {
"type": "string"
},
"customer_count": {
"type": "number"
},
"is_subscribed_for_sms_updates": {
"type": "boolean"
},
"is_follow_up_email_disabled": {
"type": "boolean"
},
"is_reminder_email_disabled": {
"type": "boolean"
},
"created_at": {
"type": "string",
"format": "datetime"
},
"source_type": {
"type": "string",
"enum": ["online", "direct", "pos", "reseller", "external-api", "kiosk", "imported", "unkown"],
"example": "online"
},
"booked_by": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"required": [
"name"
],
"additionalProperties": false
}
]
}
},
"required": [
"pk",
"uuid",
"availability",
"contact",
"company",
"affiliate_company",
"customers",
"invoice_price",
"invoice_price_display",
"display_id",
"external_id",
"order",
"status",
"rebooked_from",
"rebooked_to",
"confirmation_url",
"voucher_number",
"receipt_subtotal",
"receipt_subtotal_display",
"receipt_taxes",
"receipt_taxes_display",
"receipt_total",
"receipt_total_display",
"amount_paid",
"amount_paid_display",
"custom_field_values",
"note",
"note_safe_html",
"pickup",
"arrival",
"effective_cancellation_policy",
"is_eligible_for_cancellation",
"agent",
"desk",
"payments",
"dashboard_url",
"customer_count",
"is_subscribed_for_sms_updates",
"is_follow_up_email_disabled",
"is_reminder_email_disabled",
"created_at",
"source_type",
"booked_by"
],
"additionalProperties": false
},
"company": {
"type": "object",
"properties": {
"shortname": {
"type": "string"
},
"name": {
"type": "string"
},
"currency": {
"type": "string"
}
},
"required": [
"shortname",
"name",
"currency"
],
"additionalProperties": false
},
"affiliate_company": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"shortname": {
"type": "string"
},
"name": {
"type": "string"
},
"currency": {
"type": "string"
}
},
"required": [
"shortname",
"name",
"currency"
],
"additionalProperties": false
}
]
},
"contact": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"phone": {
"type": "string"
},
"phone_country": {
"type": ["string", "null"]
},
"normalized_phone": {
"type": "string"
},
"language": {
"type": "string"
},
"email": {
"type": "string"
},
"is_subscribed_for_email_updates": {
"type": "boolean"
}
},
"required": ["name", "phone", "phone_country", "normalized_phone", "email", "is_subscribed_for_email_updates"],
"additionalProperties": false
},
"customer": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"checkin_url": {
"type": "string"
},
"checkin_status": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/definitions/checkin_status"
}
]
},
"invoice_cost": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"feeable": {
"type": "number"
},
"price": {
"type": ["number", "null"]
},
"tax": {
"type": "number"
},
"tax_by_type": {
"type": "object"
},
"taxable": {
"type": "number"
},
"total": {
"type": "number"
}
}
}
]
},
"total_cost": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"feeable": {
"type": "number"
},
"price": {
"type": ["number", "null"]
},
"tax": {
"type": "number"
},
"tax_by_type": {
"type": "object"
},
"taxable": {
"type": "number"
},
"total": {
"type": "number"
}
}
}
]
},
"customer_type_rate": {
"$ref": "#/definitions/customer_type_rate"
},
"custom_field_values": {
"type": "array",
"items": {
"$ref": "#/definitions/custom_field_value"
}
}
},
"required": ["pk", "checkin_url", "customer_type_rate", "custom_field_values"],
"additionalProperties": false
},
"checkin_status": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"name": {
"type": "string"
},
"type": {
"type": "string"
}
},
"required": ["pk", "name", "type"],
"additionalProperties": false
},
"customer_type": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"singular": {
"type": "string"
},
"plural": {
"type": "string"
}
},
"required": ["pk", "singular", "plural"],
"additionalProperties": false
},
"customer_prototype": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"display_name": {
"type": "string"
}
},
"required": ["pk", "display_name"],
"additionalProperties": false
},
"customer_type_rate": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"customer_type": {
"$ref": "#/definitions/customer_type"
},
"customer_prototype": {
"$ref": "#/definitions/customer_prototype"
}
},
"required": [
"pk",
"customer_type",
"customer_prototype"
],
"additionalProperties": false
},
"custom_field": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"type": {
"type": "string",
"enum": ["yes-no", "short", "long", "extended-option", "count", "multi-campaign"]
},
"is_required": {
"type": "boolean"
},
"description": {
"type": "string"
},
"description_safe_html": {
"type": "string"
},
"name": {
"type": "string"
},
"title": {
"type": "string"
},
"booking_notes": {
"type": "string"
},
"booking_notes_safe_html": {
"type": "string"
},
"modifier_kind": {
"type": "string"
},
"modifier_type": {
"type": "string"
},
"offset": {
"type": "number"
},
"percentage": {
"type": "number"
},
"is_always_per_customer": {
"type": "boolean"
},
"is_taxable": {
"type": "boolean"
}
},
"required": [
"pk",
"type",
"is_required",
"description",
"description_safe_html",
"name",
"booking_notes",
"booking_notes_safe_html",
"offset"
],
"additionalProperties": false
},
"custom_field_instance": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"custom_field": {
"$ref": "#/definitions/custom_field"
}
},
"required": ["pk", "custom_field"],
"additionalProperties": false
},
"custom_field_value": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"custom_field": {
"$ref": "#/definitions/custom_field"
},
"name": {
"type": "string"
},
"value": {
"type": "string",
"maxLength": 2048
},
"display_value": {
"type": "string",
"maxLength": 2048
}
},
"required": ["pk", "custom_field", "name", "value", "display_value"],
"additionalProperties": false
},
"item": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"name": {
"type": "string"
}
},
"required": ["pk", "name"],
"additionalProperties": false
},
"pickup": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"time": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"description_safe_html": {
"type": "string"
},
"map_url": {
"type": "string"
},
"display_text": {
"type": "string"
}
},
"required": [
"time",
"name",
"description",
"description_safe_html",
"map_url",
"display_text"
],
"additionalProperties": false
}
]
},
"arrival": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"time": {
"type": "string"
},
"notes": {
"type": "string"
},
"notes_safe_html": {
"type": "string"
},
"display_text": {
"type": "string"
}
},
"required": [
"time",
"notes",
"notes_safe_html",
"display_text"
],
"additionalProperties": false
}
]
},
"effective_cancellation_policy": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"cutoff": {
"oneOf": [
{
"type": "string"
},
{
"type": "null"
}
]
}
},
"required": [
"type",
"cutoff"
],
"additionalProperties": false
},
"agent": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"name": {
"type": "string"
}
},
"required": [
"pk",
"name"
],
"additionalProperties": false
}
]
},
"desk": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"name": {
"type": "string"
}
},
"required": [
"pk",
"name"
],
"additionalProperties": false
}
]
},
"payment": {
"type": "object",
"properties": {
"amount_paid": {
"type": ["number", "null"]
},
"amount_paid_display": {
"type": ["string", "null"]
},
"created_at": {
"type": "string",
"maxLength": 2048
},
"currency": {
"type": "string",
"maxLength": 3
},
"initial_amount_paid": {
"type": ["number", "null"]
},
"initial_amount_paid_display": {
"type": ["string", "null"]
},
"pk": {
"type": "number"
},
"refunds": {
"type": "array",
"items": {
"$ref": "#/definitions/refund"
}
},
"type": {
"type": "string",
"maxLength": 2048
},
"in_store_payment_type": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"name": {
"type": "string",
"maxLength": 128
}
},
"required": [
"pk",
"name"
]
}
]
},
"status": {
"type": "string",
"maxLength": 2048
}
},
"required": [
"amount_paid",
"amount_paid_display",
"created_at",
"currency",
"initial_amount_paid",
"initial_amount_paid_display",
"pk",
"refunds",
"type",
"in_store_payment_type",
"status"
],
"additionalProperties": false
},
"refund": {
"type": "object",
"properties": {
"amount_refunded": {
"type": ["number", "null"]
},
"amount_refunded_display": {
"type": ["string", "null"]
},
"created_at": {
"type": "string",
"maxLength": 2048
},
"is_cancelled": {
"type": "boolean"
},
"pk": {
"type": "number"
}
},
"required": ["amount_refunded", "amount_refunded_display", "created_at", "pk"],
"additionalProperties": false
},
"waiver_signatures": {
"type": "object",
"properties": {
"fareharbor": {
"$ref": "#/definitions/fh_waiver_signatures"
}
},
"additionalProperties": false
},
"fh_waiver_signatures": {
"type": "array",
"items": {
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email",
"example": "johnsmith@example.com"
},
"first_name": {
"type": "string",
"example": "John"
},
"last_name": {
"type": "string",
"example": "Smith"
},
"is_marketing_allowed": {
"type": "boolean",
"description": "Whether the person signing the waiver has opted in for marketing communications.",
"example": true
},
"is_customer_parent": {
"type": "boolean",
"description": "Indicating if the signature has any related minor records.",
"example": false
},
"dob": {
"type": ["string", "null"],
"example": "1991-01-05"
},
"phone_number": {
"type": ["string", "null"],
"example": "+16468109900"
},
"address_line": {
"type": ["string", "null"],
"example": "7824 15th Ave"
},
"city": {
"type": ["string", "null"],
"example": "Brooklyn"
},
"state_province": {
"type": ["string", "null"],
"example": "NY"
},
"postcode": {
"type": ["string", "null"],
"example": "11228"
},
"country": {
"type": ["string", "null"],
"example": "US"
}
},
"required": [
"email",
"first_name",
"last_name",
"is_marketing_allowed",
"is_customer_parent",
"dob",
"phone_number",
"address_line",
"city",
"state_province",
"postcode",
"country"
],
"additionalProperties": false
},
"description": "A list of FareHarbor waivers signatures with details."
}
}
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"item": {
"$ref": "#/definitions/item"
}
},
"required": ["item"],
"additionalProperties": false,
"definitions": {
"item": {
"type": "object",
"properties": {
"pk": {
"type": "number"
},
"name": {
"type": "string"
},
"company": {
"$ref": "#/definitions/company"
},
"external_api_url": {
"type": "string"
},
"dashboard_url": {
"type": "string"
}
},
"required": [
"pk",
"name",
"company",
"external_api_url",
"dashboard_url"
]
},
"company": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"shortname": {
"type": "string"
},
"currency": {
"type": "string"
}
},
"required": [
"name",
"shortname",
"currency"
]
}
}
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"crew_member": {
"$ref": "#/definitions/crew_member"
}
},
"required": ["crew_member"],
"additionalProperties": false,
"definitions": {
"crew_member": {
"type": "object",
"properties": {
"pk": { "type": "number" },
"user": { "$ref": "#/definitions/user" },
"role": { "$ref": "#/definitions/role" },
"note": { "type": "string" },
"availability_id": { "type": "number" },
"status": { "type": "string" }
},
"required": [
"pk",
"user",
"role",
"note",
"availability_id",
"status"
],
"additionalProperties": false
},
"user": {
"type": "object",
"properties": {
"name": { "type": "string" },
"username": { "type": "string" }
},
"required": ["name", "username"],
"additionalProperties": false
},
"role": {
"type": "object",
"properties": {
"pk": { "type": "number" },
"short_name": { "type": "string" }
},
"required": ["pk", "short_name"],
"additionalProperties": false
}
}
}
This section describes some best practices for integrating with FH using webhooks and APIs.
Before writing software to integrate with FareHarbor webhooks, look into using Zapier or something similar. In many cases, doing an integration this way will be quicker, easier, more reliable, and less expensive than doing it yourself with your own servers and custom software.
In order to integrate with the FareHarbor webhooks and/or API directly, without using Zapier or the like, you will need time from experienced software engineers. If you do not have them on staff, you may need to contract them and manage them. This is not always easy.
The Booking UUID
The most important field in the booking schema is the "uuid" field. IF YOU RECEIVE TWO WEBHOOKS WITH THE SAME UUID, THEY ARE TALKING ABOUT THE SAME BOOKING. This is the most important thing to understand about bookings.
You will likely receive multiple webhooks for the same booking. For instance, you will receive one when it's created, and you may receive another if the contact information is updated, or if a customer checkin occurs.
For any given uuid, the most recent webhook received will contain the most up-to-date data.
You can always retrieve the most recent details for a booking using the Retrive Bookings endpoint, Bookings:
GET /companies/<shortname>/bookings/<Booking.uuid>/
The Customer PK
Another important field is the "customers" field. This field contains a list of customers. Each customer will have its own "pk". The PK is a globally-unique identifier for the customer.
The details of a booking may change, but as long as it is not rebooked, the customer PK will not change, and can be used as an ID within your system, directly or indirectly.
If you receive a webhook from FareHarbor for a booking that is already recorded in your system, this new webhook may contain updated information. Using the PK, you can check each customer's data to see if any piece of that customer's data has changed--the contents of a custom field, for instance.
When a rebooking occurs, customer PKs are reassigned. For most practical purposes, you can treat a rebooking event the same as cancellation of the old booking and creation of the new booking. Data associated with the old booking are no longer relevant.
Using the External API, it is possible to retrieve all existing bookings.
In pseudocode, it looks like this:
retrieve a list of companies via the [Companies endpoint](#tag/Company-Endpoints)
for each company,
retrieve a list of items via the [Items endpoint](#tag/Items-Endpoints)
for each item,
retrieve lists of availabilities via the [Availabilities endpoint](#tag/Availabilities-Endpoints)
for each availability,
retrieve a list of bookings via the [Availability Bookings endpoint](#tag/Bookings-Endpoints/operation/get-bookings)
There is sample python code to retrieve all bookings here.
I am implementing a webhook receiver on my server. What HTTP status should it return?
Answer
Your webhook receiver should always return a 200 status, to acknowledge that the payload was received and understood. If it does not return a 200 status, then FareHarbor may resend the webhook some number of times, and if there is still no 200, FareHarbor will interpret this to mean that your webhook receiver is misconfigured or malfunctioning in some way. If this happens too often, FareHarbor might deactivate your webhook. See Failing Webhooks
This is standard practice for webhooks. This is not REST.
I have FareHarbor webhooks configured. I am seeing things in my FareHarbor dashboard that indicate that the webhooks are failing with error status (500 or 400-something). The message says:
Error: request unsuccessful: 500 Server Error: Internal Server Error for url: https://my.webhook.url/
(or something like that).
What should I do?
Answer
First, it is important to understand that these HTTP status codes are generated by the RECEIVING server (i.e., your server, or whatever server is named in the "Webhook URL" configuration on your dashboard). These status codes are being returned TO the FareHarbor server, which is recording them and showing them to you on the booking page.
A 500 response indicates that FareHarbor sent a webhook, but the receiving server experienced an unexpected fatal error--informally, it "crashed". To resolve this, contact the person who is responsible for your server, and ask them to look through the server logs around the time that webhook was sent. This should provide some clues about the problem.
A 40x response indicates that the receiving server did not like the data for some reason. Maybe the authentication was improper, or some fields were missing that it was expecting, or the webhook URL was incorrect on the FareHarbor dashboard.
If the server returns a 405 response ("Method Not Allowed"), it means that it was not prepared to handle a POST request. FareHarbor always uses POST for webhooks. Please check your server configuration and code and ensure that it is preapred to receive POSTs (and not just GETs, for instance).
In either case (500 or a 40x), it is up to folks on your side to resolve the problem. It may require a reconfiguration or modification of your server software. Also, ensure that your server's SSL certificate has not expired, and that is valid for the URL in your webhook URL.
It is unlikely that the problem lies with FareHarbor. As a general policy, FareHarbor does not make changes to the API and webhooks that would break existing partner implementations.
In order to debug problems with webhooks, you may want to cause the webhook to be resent. See below for how to do that.
I missed a webhook for a specific booking. Maybe the webhook was sent, but it received a 400 or 500 response. Or maybe it seems like the webhook was never sent. What can I do?
Answer
The easiest way to resend a webhook for a specific booking is to change something insignificant on the booking in question. Changing the booking note is often a good choice. The webhook should be resent shortly after any change to the booking.
If the webhook received a 500 before and if it receives a 500 again, then your server software likely needs to be modified or reconfigured. Please talk to your technical staff.
If the webhook receives a 40x, then check that the webhook URL is correct, and confirm that certificates, security keys, etc. are in place.
FareHarbor failed to send me webhooks for some bookings, rebookings, and/or cancellations, but I don't know which ones. What should I do?
Answer
FareHarbor tries very hard to send webhooks for new or changed bookings. If FareHarbor fails on the first attempt, it will retry repeatedly over some window of time. If the server RECEIVING the webhooks (your server) is down for a long time for some reason, there is a chance that the webhooks won't be delivered.
In this case, the missing bookings can be retrieved using the Availability Bookings endpoint, which allows you to retieve a list of all bookings for a particular Availability. See Availability bookings. If you need more details than are provided by this endpoint, then you can call the Retrieve Booking Endpoint to retrieve the full details for each booking.
I receive each webhook TWICE, or more.
Answer
Is it possible that you have multiple api keys configured to send webhooks?
Beyond that:
A wide variety of events on the FareHarbor side trigger webhooks. Some examples include changes to contact details, check-ins, text message reminders sent, and so on. Many of these may not be relevant to your particular integration. Each webhook contains complete data about the booking.
You may receive multiple identical or nearly ideantical webhooks for the same booking. This may happen occasionally or regularly. This is normal. Your software must be prepared to receive identical webhooks without malfunctioning. Keep reading to learn how to know how to handle this situation and stay in sync with the bookings that exist in the FareHarbor system.
How can I guarantee that the webhook we receive is from FareHarbor, and not from someone else who somehow guessed the URL?
Answer
Choose a hard-to-guess path or query parameter
You are free to use whatever path you like in the webhook address you provide to FareHarbor. For instance, if you use:
https://mycompany.com/EE5746FDB4054852/fareharbor-webhook/
then it will be very hard to guess.
Or if you prefer, you can use something like
https://mycompany.com/fareharbor-webhook/?key=EE5746FDB4054852
and check that you receive the expected query parameter.
Call the External API to verify booking data
NOTE: External API access is granted on a on a case by case basis. To request access please contact your Account Manager or FareHarbor Support.
Another security strategy:
Whenever you receive a webhook, call the Retrieve Booking Endpoint of the External API to retrieve the booking data: Retrieve booking endpoint.
Then use the retrieved data rather than the webhook payload data.
This eliminates the potential negative impact of any "forged" webhook. So even if someone does ascertain your webhook URL, they will not be able to compromise your data integrity.
Incoroprating authorization headers into the webhook
FareHarbor does not provide a way to incorporate custom headers into the webhook that is sent. If you wish to use a shared secret to increase security, the secret can be included in the webhook URL itself, either as part of the path or as a query parameter (see above).
Using IP address-based ACLs or allowlists to validate the source of webhooks
Because FareHarbor uses distributed cloud computing, our servers' IP addresses may change at any moment without notice. Therefore we do not recommend that our partners use ACLs or allowlists for security.
We use a CRM that has a public API. Can FareHarbor integrate with that CRM? Or with other third-party public APIs? Is there some way that I can plug FareHarbor webhooks into other people's APIs?
Answer
The easiest way to plug FareHarbor webhooks into other people's APIs is using Zapier, or a similar service. Zapier, for instance, was created for exactly this purpose, and allows FareHarbor to connect to 5000+ other services: https://zapier.com/apps/fareharbor/integrations
If the service you need (your CRM or whatever) is not on this list, that means that they do not work with Zapier. Consider contacting them and asking them to integrate with Zapier. See below for more about Zapier.
What are online bookings statuses?
Answer
Online Booking Status: Each availability has an online booking status, which controls how it can be viewed and booked by online customers. In most cases, the status will be set to auto
, which automatically prevents online customers from booking after a certain time cutoff, based on item’s settings. The other statuses include open
, call
, closed
, cancelled
.
These statuses are included in the Bookings only and Booking + payments webhooks.
For a complete description of these statuses and their meaning, go to https://help.fareharbor.com/dashboard/availabilities/updating/online-booking-status/.