curl --request POST \
--url https://api.gojinko.com/v1/car_cancel_preview \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"booking_ref": "JNK-8PT9VS",
"last_name": "Doe"
}
'import requests
url = "https://api.gojinko.com/v1/car_cancel_preview"
payload = {
"booking_ref": "JNK-8PT9VS",
"last_name": "Doe"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({booking_ref: 'JNK-8PT9VS', last_name: 'Doe'})
};
fetch('https://api.gojinko.com/v1/car_cancel_preview', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.gojinko.com/v1/car_cancel_preview",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'booking_ref' => 'JNK-8PT9VS',
'last_name' => 'Doe'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.gojinko.com/v1/car_cancel_preview"
payload := strings.NewReader("{\n \"booking_ref\": \"JNK-8PT9VS\",\n \"last_name\": \"Doe\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.gojinko.com/v1/car_cancel_preview")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"booking_ref\": \"JNK-8PT9VS\",\n \"last_name\": \"Doe\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gojinko.com/v1/car_cancel_preview")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"booking_ref\": \"JNK-8PT9VS\",\n \"last_name\": \"Doe\"\n}"
response = http.request(request)
puts response.read_body{
"cancellation_id": "ccl_2f7c9a4e8b1d4c6f9e3a5b7d1c2e4f6a",
"cancellable": true,
"fee_known": true,
"fee_type": "cancellation",
"fee": {
"value": 41250,
"currency": "EUR",
"decimal_places": 2,
"display": "EUR 412.50"
},
"paid": {
"value": 41250,
"currency": "EUR",
"decimal_places": 2,
"display": "EUR 412.50"
},
"refund_amount": {
"value": 41250,
"currency": "EUR",
"decimal_places": 2,
"display": "EUR 412.50"
},
"currency": "EUR",
"non_refundable": true,
"refund_pending_review": true,
"refund_review_reason": "the cancellation fee for this rental could not be established; a person will complete the cancellation",
"manual_required": false,
"expires_at": "2026-09-21T10:15:00Z"
}{
"error": {
"code": "BAD_REQUEST",
"message": "Malformed JSON in request body.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "AUTH_REQUIRED",
"message": "Invalid or expired API key.",
"doc_url": "https://docs.gojinko.com/authentication/api-keys"
}
}{
"error": {
"code": "PAYMENT_REQUIRED",
"message": "Insufficient balance — this call costs $0.0150 and your organization has $0.0000 available. Top up at https://dashboard.gojinko.com/developers/billing/topup",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "NOT_FOUND",
"message": "booking not found"
}
}{
"error": {
"code": "CONFLICT",
"message": "an exchange is in progress for this rental; wait for it to finish before cancelling"
},
"code": "active_operation_exists"
}{
"error": {
"code": "GONE",
"message": "The resource no longer exists.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "BAD_REQUEST",
"message": "A required field is missing or invalid.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "RATE_LIMITED",
"message": "Too many requests. Retry after the Retry-After delay.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "UPSTREAM_REJECTED",
"message": "The request was declined for this offer. Try another offer.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "UPSTREAM_UNAVAILABLE",
"message": "The service is temporarily unavailable. Retry after the Retry-After delay.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "UPSTREAM_TIMEOUT",
"message": "The request timed out before a result was available. Retry the request.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}car-cancel-preview
Preview the cost of cancelling a car rental booking
curl --request POST \
--url https://api.gojinko.com/v1/car_cancel_preview \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"booking_ref": "JNK-8PT9VS",
"last_name": "Doe"
}
'import requests
url = "https://api.gojinko.com/v1/car_cancel_preview"
payload = {
"booking_ref": "JNK-8PT9VS",
"last_name": "Doe"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({booking_ref: 'JNK-8PT9VS', last_name: 'Doe'})
};
fetch('https://api.gojinko.com/v1/car_cancel_preview', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.gojinko.com/v1/car_cancel_preview",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'booking_ref' => 'JNK-8PT9VS',
'last_name' => 'Doe'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.gojinko.com/v1/car_cancel_preview"
payload := strings.NewReader("{\n \"booking_ref\": \"JNK-8PT9VS\",\n \"last_name\": \"Doe\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.gojinko.com/v1/car_cancel_preview")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"booking_ref\": \"JNK-8PT9VS\",\n \"last_name\": \"Doe\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gojinko.com/v1/car_cancel_preview")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"booking_ref\": \"JNK-8PT9VS\",\n \"last_name\": \"Doe\"\n}"
response = http.request(request)
puts response.read_body{
"cancellation_id": "ccl_2f7c9a4e8b1d4c6f9e3a5b7d1c2e4f6a",
"cancellable": true,
"fee_known": true,
"fee_type": "cancellation",
"fee": {
"value": 41250,
"currency": "EUR",
"decimal_places": 2,
"display": "EUR 412.50"
},
"paid": {
"value": 41250,
"currency": "EUR",
"decimal_places": 2,
"display": "EUR 412.50"
},
"refund_amount": {
"value": 41250,
"currency": "EUR",
"decimal_places": 2,
"display": "EUR 412.50"
},
"currency": "EUR",
"non_refundable": true,
"refund_pending_review": true,
"refund_review_reason": "the cancellation fee for this rental could not be established; a person will complete the cancellation",
"manual_required": false,
"expires_at": "2026-09-21T10:15:00Z"
}{
"error": {
"code": "BAD_REQUEST",
"message": "Malformed JSON in request body.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "AUTH_REQUIRED",
"message": "Invalid or expired API key.",
"doc_url": "https://docs.gojinko.com/authentication/api-keys"
}
}{
"error": {
"code": "PAYMENT_REQUIRED",
"message": "Insufficient balance — this call costs $0.0150 and your organization has $0.0000 available. Top up at https://dashboard.gojinko.com/developers/billing/topup",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "NOT_FOUND",
"message": "booking not found"
}
}{
"error": {
"code": "CONFLICT",
"message": "an exchange is in progress for this rental; wait for it to finish before cancelling"
},
"code": "active_operation_exists"
}{
"error": {
"code": "GONE",
"message": "The resource no longer exists.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "BAD_REQUEST",
"message": "A required field is missing or invalid.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "RATE_LIMITED",
"message": "Too many requests. Retry after the Retry-After delay.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "UPSTREAM_REJECTED",
"message": "The request was declined for this offer. Try another offer.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "UPSTREAM_UNAVAILABLE",
"message": "The service is temporarily unavailable. Retry after the Retry-After delay.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "UPSTREAM_TIMEOUT",
"message": "The request timed out before a result was available. Retry the request.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}fee_known: false means the fee could not be established, render it as “we will confirm the fee”, never as free cancellation. The returned cancellation_id is required by car_cancel_commit, and binds until expires_at where one is given. cancellable: false with manual_required: true means the cancellation cannot be completed online (fee unknown, rental changed after payment, fee in another currency or above the rental) and refund_review_reason says why: it is not a dead end, once the customer agrees, commit it with manual_ok: true and a Jinko agent completes it. cancellable: false without that flag is a rental that cannot be cancelled at all (already cancelled, or over), carrying the cancellation that stands where there is one. Guest-authenticated: booking_ref + last_name; a wrong pair returns 404 rather than confirming the booking’s existence.Authorizations
Body
Jinko booking reference. Call get_booking first, then select its item_id for servicing.
1"JNK-A0AUR2"
Stable booked item ID from get_booking items[].item_id. Preserved across exchanges. Omit only when the booking has exactly one item of the requested domain; otherwise a 409 returns items to choose from.
0 < x <= 900719925474099142
Required for guest lookup. A credential that owns the booking may omit it; ownership is checked by the platform.
1"Doe"
Show child attributes
Show child attributes
Response
Cancellation quote
Opaque reference of this preview ("ccl_…"). Pass to car_cancel_commit — it binds the commit to the fee quoted here. Treat as an opaque string; the format may evolve.
"ccl_2f7c9a4e8b1d4c6f9e3a5b7d1c2e4f6a"
true
false means the fee could not be established — UNKNOWN, not free. Render as "we will confirm the fee".
true
"cancellation"
Show child attributes
Show child attributes
What the customer originally paid.
Show child attributes
Show child attributes
paid minus fee. Absent whenever the fee is unknown — absent is not zero.
Show child attributes
Show child attributes
"EUR"
true means the refund figure is right but will be issued by hand rather than automatically (the rental was changed after it was paid for). The cancellation itself still goes through online; not a failure.
Why a person is involved, whenever manual_required or refund_pending_review is true, in words the customer can be shown. Where the reason would be the supplier’s own words — as on a cancellable: false preview of a rental that cannot be cancelled at all — it reads “This request needs manual handling by Jinko support.”
"the cancellation fee for this rental could not be established; a person will complete the cancellation"
true means this cancellation cannot be completed online — the fee could not be established, the rental was changed after it was paid for, or the fee is in another currency or above the rental. cancellable is false, no refund figure is given and refund_review_reason says why. It is not a dead end: car_cancel_commit takes this cancellation_id with manual_ok: true, which records the cancellation for a Jinko agent to complete and answers state: pending with refund_pending_review: true. Without the flag such a commit is refused 409 manual_required, so a customer is never put in an agent queue unasked. Absent (or false) on every quote that can be committed online.
false
When this preview stops being committable (RFC 3339). A commit after it is refused 409 quote_expired; preview again. Absent where the quote carries no deadline.
"2026-09-21T10:15:00Z"
