curl --request POST \
--url https://api.gojinko.com/v1/car_cancel_commit \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"booking_ref": "JNK-8PT9VS",
"last_name": "Doe",
"cancellation_id": "ccl_2f7c9a4e8b1d4c6f9e3a5b7d1c2e4f6a"
}
'import requests
url = "https://api.gojinko.com/v1/car_cancel_commit"
payload = {
"booking_ref": "JNK-8PT9VS",
"last_name": "Doe",
"cancellation_id": "ccl_2f7c9a4e8b1d4c6f9e3a5b7d1c2e4f6a"
}
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',
cancellation_id: 'ccl_2f7c9a4e8b1d4c6f9e3a5b7d1c2e4f6a'
})
};
fetch('https://api.gojinko.com/v1/car_cancel_commit', 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_commit",
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',
'cancellation_id' => 'ccl_2f7c9a4e8b1d4c6f9e3a5b7d1c2e4f6a'
]),
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_commit"
payload := strings.NewReader("{\n \"booking_ref\": \"JNK-8PT9VS\",\n \"last_name\": \"Doe\",\n \"cancellation_id\": \"ccl_2f7c9a4e8b1d4c6f9e3a5b7d1c2e4f6a\"\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_commit")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"booking_ref\": \"JNK-8PT9VS\",\n \"last_name\": \"Doe\",\n \"cancellation_id\": \"ccl_2f7c9a4e8b1d4c6f9e3a5b7d1c2e4f6a\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gojinko.com/v1/car_cancel_commit")
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 \"cancellation_id\": \"ccl_2f7c9a4e8b1d4c6f9e3a5b7d1c2e4f6a\"\n}"
response = http.request(request)
puts response.read_body{
"cancellation_id": "ccl_2f7c9a4e8b1d4c6f9e3a5b7d1c2e4f6a",
"state": "confirmed",
"fee_known": true,
"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"
},
"refund_pending_review": true,
"stripe_refund_id": "<string>",
"rejected_reason": "<string>",
"completed_at": "2026-08-20T15:18: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": "this quote cannot be committed"
},
"code": "manual_required"
}{
"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-commit
Cancel a car rental booking
curl --request POST \
--url https://api.gojinko.com/v1/car_cancel_commit \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"booking_ref": "JNK-8PT9VS",
"last_name": "Doe",
"cancellation_id": "ccl_2f7c9a4e8b1d4c6f9e3a5b7d1c2e4f6a"
}
'import requests
url = "https://api.gojinko.com/v1/car_cancel_commit"
payload = {
"booking_ref": "JNK-8PT9VS",
"last_name": "Doe",
"cancellation_id": "ccl_2f7c9a4e8b1d4c6f9e3a5b7d1c2e4f6a"
}
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',
cancellation_id: 'ccl_2f7c9a4e8b1d4c6f9e3a5b7d1c2e4f6a'
})
};
fetch('https://api.gojinko.com/v1/car_cancel_commit', 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_commit",
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',
'cancellation_id' => 'ccl_2f7c9a4e8b1d4c6f9e3a5b7d1c2e4f6a'
]),
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_commit"
payload := strings.NewReader("{\n \"booking_ref\": \"JNK-8PT9VS\",\n \"last_name\": \"Doe\",\n \"cancellation_id\": \"ccl_2f7c9a4e8b1d4c6f9e3a5b7d1c2e4f6a\"\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_commit")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"booking_ref\": \"JNK-8PT9VS\",\n \"last_name\": \"Doe\",\n \"cancellation_id\": \"ccl_2f7c9a4e8b1d4c6f9e3a5b7d1c2e4f6a\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gojinko.com/v1/car_cancel_commit")
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 \"cancellation_id\": \"ccl_2f7c9a4e8b1d4c6f9e3a5b7d1c2e4f6a\"\n}"
response = http.request(request)
puts response.read_body{
"cancellation_id": "ccl_2f7c9a4e8b1d4c6f9e3a5b7d1c2e4f6a",
"state": "confirmed",
"fee_known": true,
"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"
},
"refund_pending_review": true,
"stripe_refund_id": "<string>",
"rejected_reason": "<string>",
"completed_at": "2026-08-20T15:18: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": "this quote cannot be committed"
},
"code": "manual_required"
}{
"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"
}
}cancellation_id from a preceding preview, binding the commit to the fee the customer saw. Safe to call twice, a committed cancellation is reported as it stands rather than repeated. state: confirmed is done; state: pending is recorded but not finished, the platform is still completing it, or a Jinko agent has it, so read car_cancel_status rather than committing again. refund_pending_review: true means the refund needs a person before it is issued. A preview that answered manual_required: true is committed with manual_ok: true, once the customer agrees: the cancellation is then recorded for a Jinko agent (state: pending, refund_pending_review: true) and nothing is sent to the rental company by this call. Without the flag that commit is refused 409 manual_required. The other 409 refusals are quote_expired (preview again), quote_drift (the refund moved; commit against the requote it names after showing the customer current.refund), active_operation_exists, not_cancellable and funds_unavailable, see CarServicingConflictCode. In every one of them nothing was cancelled.Authorizations
Body
Jinko booking reference. Call get_booking first, then select its item_id for servicing.
1"JNK-A0AUR2"
The "ccl_…" reference from a preceding car_cancel_preview. Binds the commit to the fee the customer saw.
1"ccl_2f7c9a4e8b1d4c6f9e3a5b7d1c2e4f6a"
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
Optional free-text cancellation reason.
"Change of plans"
Send true to commit a preview that answered manual_required: true. The cancellation is then recorded for a Jinko agent — NOTHING is sent to the rental company by this call — and the answer is state: pending with refund_pending_review: true; the agent completes it and settles the refund by hand, and car_cancel_status reports the outcome. Without the flag such a commit is refused 409 manual_required, so a customer is never put in an agent queue unasked: send it only once the customer has agreed to that. On a preview that can be committed online the flag changes nothing.
false
Response
Cancellation result
"ccl_2f7c9a4e8b1d4c6f9e3a5b7d1c2e4f6a"
confirmed — cancelled and the refund issued or on its way. pending — recorded but not finished: the platform is still completing it, or (with refund_pending_review: true) a Jinko agent has it; read car_cancel_status, do not commit again. rejected — the rental company declined; the booking still stands and rejected_reason says why. failed — the attempt did not complete; read car_cancel_status before trying again.
"confirmed"
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
true means the booking IS cancelled (or, with state: pending, recorded for a Jinko agent) but the refund needs a person before it is issued — do not quote refund_amount as final.
"2026-08-20T15:18:00Z"
