curl --request POST \
--url https://api.example.com/v1/flight_refund_status \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"booking_ref": "JNK-A0AUR2",
"last_name": "Carrard",
"operation": "svc_01J7ZR5Q2KME8V4T"
}
'import requests
url = "https://api.example.com/v1/flight_refund_status"
payload = {
"booking_ref": "JNK-A0AUR2",
"last_name": "Carrard",
"operation": "svc_01J7ZR5Q2KME8V4T"
}
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-A0AUR2',
last_name: 'Carrard',
operation: 'svc_01J7ZR5Q2KME8V4T'
})
};
fetch('https://api.example.com/v1/flight_refund_status', 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.example.com/v1/flight_refund_status",
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-A0AUR2',
'last_name' => 'Carrard',
'operation' => 'svc_01J7ZR5Q2KME8V4T'
]),
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.example.com/v1/flight_refund_status"
payload := strings.NewReader("{\n \"booking_ref\": \"JNK-A0AUR2\",\n \"last_name\": \"Carrard\",\n \"operation\": \"svc_01J7ZR5Q2KME8V4T\"\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.example.com/v1/flight_refund_status")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"booking_ref\": \"JNK-A0AUR2\",\n \"last_name\": \"Carrard\",\n \"operation\": \"svc_01J7ZR5Q2KME8V4T\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v1/flight_refund_status")
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-A0AUR2\",\n \"last_name\": \"Carrard\",\n \"operation\": \"svc_01J7ZR5Q2KME8V4T\"\n}"
response = http.request(request)
puts response.read_body{
"operation": "svc_01J7ZR5Q2KME8V4T",
"state": "in_progress",
"reason": "settlement_review",
"park_deadline": "2026-09-10T12:15:00Z",
"next_run_at": "2026-09-03T12:20:00Z",
"provider": {
"state": "cancelled",
"provider_status": "CANCELLED_WITH_CHARGES",
"references": {
"booking_id": "eRR9inUfI",
"cancellation_reference": "cxl_2f90a1c3"
},
"documents": [
{
"number": "0012345678901",
"type": "TKT",
"state": "ACTIVE",
"recoverable": false
}
]
},
"money": {
"value": 41250,
"amount": 123,
"currency": "USD",
"decimal_places": 2,
"direction": "refund",
"vehicle_state": "paid",
"stripe_reference": "re_3UBIxK2eZvKYlo2C"
},
"operation_kind": "cancel"
}{
"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/api-reference/authentication"
}
}{
"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 already in progress for this booking",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "GONE",
"message": "The resource no longer exists.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "BAD_REQUEST",
"message": "origins: origins is required; trip_type: trip_type is required",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit or quota exceeded.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "UPSTREAM_REJECTED",
"message": "sabre-rest BargainFinderMaxRQ failed with status 400: 27131 - Number of connection locations exceeds maximum allowed",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "UPSTREAM_UNAVAILABLE",
"message": "All flight providers are temporarily unable to serve this search. Please retry later. Provider reasons: sabre-rest: provider temporarily closed; travelfusion: quota exhausted",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "UPSTREAM_TIMEOUT",
"message": "sabre-rest BargainFinderMaxRQ timed out after 30s",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}flight-refund-status
Check how a flight refund or void ended
curl --request POST \
--url https://api.example.com/v1/flight_refund_status \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"booking_ref": "JNK-A0AUR2",
"last_name": "Carrard",
"operation": "svc_01J7ZR5Q2KME8V4T"
}
'import requests
url = "https://api.example.com/v1/flight_refund_status"
payload = {
"booking_ref": "JNK-A0AUR2",
"last_name": "Carrard",
"operation": "svc_01J7ZR5Q2KME8V4T"
}
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-A0AUR2',
last_name: 'Carrard',
operation: 'svc_01J7ZR5Q2KME8V4T'
})
};
fetch('https://api.example.com/v1/flight_refund_status', 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.example.com/v1/flight_refund_status",
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-A0AUR2',
'last_name' => 'Carrard',
'operation' => 'svc_01J7ZR5Q2KME8V4T'
]),
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.example.com/v1/flight_refund_status"
payload := strings.NewReader("{\n \"booking_ref\": \"JNK-A0AUR2\",\n \"last_name\": \"Carrard\",\n \"operation\": \"svc_01J7ZR5Q2KME8V4T\"\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.example.com/v1/flight_refund_status")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"booking_ref\": \"JNK-A0AUR2\",\n \"last_name\": \"Carrard\",\n \"operation\": \"svc_01J7ZR5Q2KME8V4T\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v1/flight_refund_status")
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-A0AUR2\",\n \"last_name\": \"Carrard\",\n \"operation\": \"svc_01J7ZR5Q2KME8V4T\"\n}"
response = http.request(request)
puts response.read_body{
"operation": "svc_01J7ZR5Q2KME8V4T",
"state": "in_progress",
"reason": "settlement_review",
"park_deadline": "2026-09-10T12:15:00Z",
"next_run_at": "2026-09-03T12:20:00Z",
"provider": {
"state": "cancelled",
"provider_status": "CANCELLED_WITH_CHARGES",
"references": {
"booking_id": "eRR9inUfI",
"cancellation_reference": "cxl_2f90a1c3"
},
"documents": [
{
"number": "0012345678901",
"type": "TKT",
"state": "ACTIVE",
"recoverable": false
}
]
},
"money": {
"value": 41250,
"amount": 123,
"currency": "USD",
"decimal_places": 2,
"direction": "refund",
"vehicle_state": "paid",
"stripe_reference": "re_3UBIxK2eZvKYlo2C"
},
"operation_kind": "cancel"
}{
"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/api-reference/authentication"
}
}{
"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 already in progress for this booking",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "GONE",
"message": "The resource no longer exists.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "BAD_REQUEST",
"message": "origins: origins is required; trip_type: trip_type is required",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit or quota exceeded.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "UPSTREAM_REJECTED",
"message": "sabre-rest BargainFinderMaxRQ failed with status 400: 27131 - Number of connection locations exceeds maximum allowed",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "UPSTREAM_UNAVAILABLE",
"message": "All flight providers are temporarily unable to serve this search. Please retry later. Provider reasons: sabre-rest: provider temporarily closed; travelfusion: quota exhausted",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "UPSTREAM_TIMEOUT",
"message": "sabre-rest BargainFinderMaxRQ timed out after 30s",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}operation handle a commit (or POST /v1/refund_commit) returned. Read-only. state is the platform view, keep polling while it is in_progress or attention_required, both of which mean the operation is still alive; attention_required means a Jinko agent has it, and park_deadline says how long that lasts. operation_kind says which operation actually ran. provider is what the airline says, including what became of each ticket and EMD, an operation has done its work when every document it covers has reached a terminal state. money is where the refund itself has got to; the two move independently, so the tickets can read refunded while the money is still in flight. Do not tell a customer they have been refunded until money.vehicle_state says paid. Same auth modes as flight_refund_preview.Authorizations
Body
The "svc_…" handle from a commit, or from POST /v1/refund_commit.
"svc_01J7ZR5Q2KME8V4T"
The CONNECTOR's own order id for this flight booking — the Sabre PNR for a Sabre booking, the TravelFusion booking reference for a TravelFusion one. NOT the airline record locator, which names the carrier's own copy of the reservation and is answered 404 here, identically to an unknown booking. OWNER mode: beyond the API authentication every call needs, this one requires a credential that OWNS the booking — a tenant-bound key reaches its whole tenant, any other credential must belong to the booking's own user. Mutually exclusive with booking_ref + last_name; sending both is rejected with 422.
"QQIUIQ"
The Jinko reference. GUEST mode: pair it with last_name and the pair identifies the booking on its own — API authentication is still required, as on every call here, but the credential does not have to own the booking. Mutually exclusive with provider_reference; one without the other is rejected with 422.
"JNK-H1ZK90"
The lead traveller's surname. Required with booking_ref, and only with it.
"Carrard"
Show child attributes
Show child attributes
Response
Where the refund or void has got to
"svc_01J7ZR5Q2KME8V4T"
Where the cancellation has got to. in_progress — running; keep polling. attention_required — stalled on something a person at Jinko has to resolve (reason names it); keep polling, and do not report it to the customer as a failure, because the booking may already be cancelled at the supplier. succeeded and failed are terminal: the supplier outcome and the money are both settled and nothing further will change.
in_progress, attention_required, succeeded, failed Why the operation is stalled. Present with state: attention_required; the value names what Jinko has to resolve, and needs nothing from the caller.
"settlement_review"
When a parked operation stops waiting for Jinko and is settled or failed. Present with state: attention_required; it is how long "keep polling" lasts.
"2026-09-10T12:15:00Z"
When the platform next drives this operation by itself. Informational — polling sooner does not make it run sooner.
"2026-09-03T12:20:00Z"
The airline's record. It can show the tickets refunded while the money is still moving — that is the normal middle of a refund, not a discrepancy.
Show child attributes
Show child attributes
The refund and where it has got to. Read vehicle_state before telling a customer they have been refunded.
Show child attributes
Show child attributes
Which operation ran — a refund under the fare rules (cancel) or a void of the original charge (void). The same field the preview quoted, so what was quoted and what ran compare directly.
cancel, void 