{"openapi":"3.0.0","x-samples-languages":["curl","javascript","node","java","kotlin","python","php","go","swift"],"info":{"version":"1.0","title":"Loyalty API","description":"If you implement an OAuth integration with Karhoo this can allow your users to use loyalty points in your system in order to pay for trips booked using Karhoo.\n\n<b>In order to have a loyalty integration with Karhoo your system needs to implement the endpoints below.</b>\n\nThe field `traveller_id` in this specification refers to the id your user has in your system. Karhoo will obtain this value during the OAuth flow.\n\nHere is how the flow will work:\n  * Karhoo will make a call daily to GET /loyalty/exchange_rates to get the exchange rates for loyalty points. Using this Karhoo will know what if the currency equivalent for one of your loyalty points.\n  * When a user attempts to book a trip Karhoo will call GET /loyalty/{traveller_id}/ballance in order to check how many loyalty points a user has and if he can use them. The information about payment with Loyalty points can be displayed in the mobile or web application.\n  * When a user books, Karhoo will make a call to the burn endpoint. If the response is a successful 204, Karhoo will continue and book a trip with the fleet the user selected. It is possible to pay only partially with Loyalty points, in that case the total value of the trip is higher then the value of the loyalty points and the difference will be covered by a credit card payment.\n  * In the event that a fleet or the user cancel the trip points can completely or partially be refunded. In that case Karhoo will call the refund endpoint to refund the points to your user.\n\nThere are two types of Tokens that are used to implement a secure connection which are sent in the header:\n  * X-API-KEY - used to get exchange rate and refund points to a specific user. This token is not linked to any user.\n  * Bearer token - used to burn points and get the balance for a user. This token is issued by your system and allows access to only the user the token refers to. We can not use a Bearer token for the refund endpoint because this can happen weeks after the moment of booking and the bearer token might have expired or could not be refreshed without the user being present anymore.\n","x-hugo-values":{"tags":["api"],"categories":["Loyalty"],"public":true,"weight":80}},"paths":{"/loyalty/exchange-rates":{"get":{"tags":["Loyalty"],"summary":"Get loyalty exchange rates","description":"In order to be able to convert a currency value such as 25 EUR to points we need to know the exchange rates for the points. A version should be returned that can be used to reference the rates at the time of the transaction.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeRatesResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/loyalty/users/{traveller_id}/balance":{"get":{"tags":["Loyalty"],"summary":"Get user loyalty points balance","description":"Provides the loyalty points balance by traveller id (the id of the user as it appears in your system).","parameters":[{"name":"traveller_id","in":"path","description":"The User ID from recognized by the loyalty program.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-CORRELATION-ID":{"description":"ID of the transaction on your side so we can reference it for debugging purposes or if we need to reconcile a transactions.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PointsBalanceResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/loyalty/users/{traveller_id}/burn":{"post":{"tags":["Loyalty"],"summary":"Burn loyalty points","description":"Karhoo will call this endpoint in order to burn loyalty points for a specific user. For example if the value of a trip is 37 EUR and the user chooses to use 1500 loyalty points (with a value of 15 EUR at a 1EUR=100points exchange rate) you will receive a request for 1500 points which will specify also the currency equivalent and the exchange rate version that was used for the operation.","parameters":[{"name":"traveller_id","in":"path","description":"The id of the user in your system.","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BurnPointsRequest"}}},"description":"request body","required":true},"responses":{"204":{"description":"Success response, no content.","headers":{"X-CORRELATION-ID":{"description":"ID of the transaction on your side so we can reference it for debugging purposes or if we need to reconcile some transactions.","schema":{"type":"string"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"Bearer":[]}]}},"/loyalty/users/{traveller_id}/refund":{"post":{"tags":["Loyalty"],"summary":"Refund loyalty points","description":"Karhoo will send you this request if points need to be refunded for a specific user. This will happen in case the booking was cancelled for example. For this endpoint Karhoo requires an API Key that can be used to refund points without the user being present. The token from the burn endpoint can not be used because it might have expired by the time we need to make this call as cancellations can happen weeks after the time of booking.","parameters":[{"name":"traveller_id","in":"path","description":"The User ID from recognized by the loyalty program.","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefundPointsRequest"}}},"description":"request body","required":true},"responses":{"204":{"description":"Success response, no content.","headers":{"X-CORRELATION-ID":{"description":"ID of the transaction on your side so we can reference it for debugging purposes or if we need to reconcile some transactions.","schema":{"type":"string"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"APIKeyHeader":[]}]}},"/healthcheck":{"get":{"tags":["Healthcheck"],"summary":"Check the health of your API","description":"This allows you to monitor the health of your API implementation.","responses":{"204":{"description":"Success response, no content. Service is ok"}}}}},"servers":[{"url":"https://your.hostname.com/"}],"components":{"securitySchemes":{"Bearer":{"description":"This is a token issued by your system that is specific for each traveller_id. Using this token we can only burn points or get the balance for the specific user the token refers to. The token is issued with the user being present as part of the Oauth flow. Will be sent as header `Authorization: Bearer {token for traveller_id issued by your system}`","type":"apiKey","name":"Authorization","in":"header"},"APIKeyHeader":{"description":"This is an API Key you provide to Karhoo. The token will be stored as a secret on the Karhoo backend and used for server-to-server communication. The token can be used to get exchange rates and earn points for any user. The advantage of this token is that we don't need the user to be present to renew it. Will be sent as header `X-API-Key: {api key issued by you and security sent to Karhoo and stored as a secret}`","type":"apiKey","in":"header","name":"X-API-Key"}},"schemas":{"PointsBalanceResponse":{"required":["points","can_burn_points"],"type":"object","properties":{"points":{"type":"number","format":"int","description":"The number of loyalty points available to burn for this user","example":1500},"can_burn_points":{"type":"boolean","example":true}}},"BurnPointsRequest":{"type":"object","required":["trip_id","points","currency_value","currency_code","exchange_rates_version","details","karhoo_transaction_id"],"properties":{"trip_id":{"type":"string","format":"uuid","description":"The ID of the trip which the traveller is burning points","example":"9361d590-7472-11e8-82da-0a580a2c041d"},"points":{"type":"number","format":"int","description":"The number of loyalty points available to burn for this user","example":1500},"currency_value":{"type":"string","description":"Currency value equivalent to the burned points","example":"15.00"},"currency_code":{"type":"string","example":"EUR","description":"The ISO 4217 code for currency used."},"exchange_rates_version":{"type":"string","example":"20200121","description":"The version returned in GET /loyalty/exchange_rates that was used to calculate the conversion rate to points"},"details":{"type":"string","description":"Human readable description of the transaction","example":"Use of loyalty points"},"karhoo_transaction_id":{"type":"string","format":"uuid","description":"The iID of the transaction on Karhoo side. You will never receive two requests with the same karhoo_transaction_id so it can be used to ensure the request is idempotent","example":"3f6271c8-6d58-440a-b051-c70b0abc516b"}}},"RefundPointsRequest":{"type":"object","required":["trip_id","points","currency_value","currency_code","exchange_rates_version","details","karhoo_transaction_id"],"properties":{"trip_id":{"type":"string","format":"uuid","description":"The ID of the trip which the traveller is burning points","example":"9361d590-7472-11e8-82da-0a580a2c041d"},"points":{"type":"number","format":"int","description":"The number of loyalty points available to burn for this user","example":1500},"currency_value":{"type":"string","description":"Currency value equivalent to the burned points","example":"15.00"},"currency_code":{"type":"string","example":"EUR","description":"The ISO 4217 code for currency used."},"exchange_rates_version":{"type":"string","example":"20200121","description":"The version returned in GET /loyalty/exchange_rates that was used to calculate the conversion rate to points"},"details":{"type":"string","description":"Human readable description of the transaction","example":"Trip cancelled"},"karhoo_transaction_id":{"type":"string","format":"uuid","description":"The ID of the transaction on Karhoo side. You will never receive two requests with the same karhoo_transaction_id so it can be used to ensure the request is idempotent","example":"3f6271c8-6d58-440a-b051-c70b0abc516b"}}},"Error":{"type":"object","properties":{"code":{"type":"string","description":"The error code in the event of a burn failure"},"message":{"type":"string","description":"The error  in the event of a burn failure"}}},"CurrencyConversion":{"type":"object","required":["currency","points"],"properties":{"currency":{"type":"string","description":"The ISO 4217 code for currency used. This represents the smallest unit of the currency_code","example":"GBP"},"points":{"type":"string","format":"int","description":"the number of loyalty points equal to the smallest unit of the currency. This is a string as the value can have decimals for some currencies for example 1 COP= 0.037 points","example":"100"}}},"ExchangeRatesResponse":{"required":["version","rates"],"type":"object","properties":{"version":{"type":"string","example":20200112},"rates":{"$ref":"#/components/schemas/Rates"}}},"Rates":{"type":"array","items":{"$ref":"#/components/schemas/CurrencyConversion"}}}},"x-readme":{"explorer-enabled":true,"proxy-enabled":true}}