Transaction batch failures
curl --request GET \
--url http://api.gu1.ai/batch-import/transaction-jobs/{jobId}/failures \
--header 'Authorization: Bearer <token>'import requests
url = "http://api.gu1.ai/batch-import/transaction-jobs/{jobId}/failures"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('http://api.gu1.ai/batch-import/transaction-jobs/{jobId}/failures', 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 => "http://api.gu1.ai/batch-import/transaction-jobs/{jobId}/failures",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "http://api.gu1.ai/batch-import/transaction-jobs/{jobId}/failures"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("http://api.gu1.ai/batch-import/transaction-jobs/{jobId}/failures")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("http://api.gu1.ai/batch-import/transaction-jobs/{jobId}/failures")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"success": true,
"jobId": "<string>",
"kind": "<string>",
"status": "<string>",
"failures": [
{}
],
"jobFailure": {},
"truncated": true,
"failuresTotal": 123
}API Reference
Transaction batch failures
Download CSV or JSON reports listing failed transaction rows for a batch import job, including row numbers, error codes, and validation messages.
GET
/
batch-import
/
transaction-jobs
/
{jobId}
/
failures
Transaction batch failures
curl --request GET \
--url http://api.gu1.ai/batch-import/transaction-jobs/{jobId}/failures \
--header 'Authorization: Bearer <token>'import requests
url = "http://api.gu1.ai/batch-import/transaction-jobs/{jobId}/failures"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('http://api.gu1.ai/batch-import/transaction-jobs/{jobId}/failures', 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 => "http://api.gu1.ai/batch-import/transaction-jobs/{jobId}/failures",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "http://api.gu1.ai/batch-import/transaction-jobs/{jobId}/failures"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("http://api.gu1.ai/batch-import/transaction-jobs/{jobId}/failures")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("http://api.gu1.ai/batch-import/transaction-jobs/{jobId}/failures")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"success": true,
"jobId": "<string>",
"kind": "<string>",
"status": "<string>",
"failures": [
{}
],
"jobFailure": {},
"truncated": true,
"failuresTotal": 123
}Endpoints
GET https://api.gu1.ai/batch-import/transaction-jobs/{jobId}/failures.csv
GET https://api.gu1.ai/batch-import/transaction-jobs/{jobId}/failures
β¦/failures.csvβ CSV file download (Content-Disposition: attachment)β¦/failuresβ JSON body
Authentication
Authorization: Bearer YOUR_API_KEY
transactions:create, entities:bulk_import, events:create.
HTTP responses
| Status | When |
|---|---|
200 | Job found (CSV download or JSON body) |
401 | Not authenticated |
403 | Missing batch-import permission |
404 | Unknown jobId or job belongs to another organization |
CSV columns
| Column | Description |
|---|---|
external_id | Transaction externalId |
code | Stable failure code β catalog |
error | Human-readable message (same as message in JSON) |
code column) are normalized on download when possible.
JSON response
boolean
Always
true when job exists.string
Batch job id.
string
transaction_batchstring
queued | running | completed | failed | β¦array
Row failures:
{ externalId, code, message }. Empty when all rows succeeded or job failed entirely before per-row collection.object
Present when
status=failed for whole-batch errors (e.g. INVALID_ENTITY_REFERENCES): { code, message, details? }.boolean
true when more than 500 failures exist. The response sample is hydrated from the stored failures.csv; download the CSV for the complete list.number
Total failed rows reported by the job artifact.
{
"success": true,
"jobId": "abc-123",
"kind": "transaction_batch",
"status": "completed",
"totalItems": 10,
"succeeded": 9,
"failed": 1,
"skipped": 0,
"failures": [
{
"externalId": "txn-009",
"code": "CONSTRAINT_VIOLATION",
"message": "β¦"
}
],
"truncated": false,
"failuresTotal": 1
}
With
batchErrorHandling=rollback_all (multipart upload default), an insert error or invalid entity refs (strict validation) aborts the batch: 0 rows created; ref detail goes to failures.csv (S3) and jobFailure, not a giant metadata array. With continue_collect_errors or stop_keep_success, invalid refs and other row failures are recorded per row and valid rows are created (or processing stops at the first failure, depending on policy).Skipped rows (duplicates)
GET https://api.gu1.ai/batch-import/transaction-jobs/{jobId}/skips.csv
skipped are not failures: the transaction was not inserted because another
transaction with the same externalId already existed in your organization. This endpoint lists
which ones, so you can tell a duplicate re-upload from a real problem.
| Column | Description |
|---|---|
external_id | Transaction externalId that already existed |
reason | Always DUPLICATE_EXTERNAL_ID |
| Status | When |
|---|---|
200 | CSV download |
404 | Unknown jobId, other organization, or SKIPS_NOT_AVAILABLE |
SKIPS_NOT_AVAILABLE means the job has no stored report: jobs that finished before this endpoint
existed, jobs with nothing skipped, and jobs sent with skipDuplicates=false (duplicates are
resolved by the database and only counted, not listed).
See also: Failure codes, Create batch transactions.Was this page helpful?