Docs / API reference
Bulk Feedback
Sends up to 1,000 payment outcomes and labels in one call, for nightly syncs and for backfilling your history.
Overview#
feedback/bulk is a POST method with a JSON body {"items": [...]}. Each item is either a payment outcome (kind: "payment", with the fields of Payment Outcome Feedback) or a label (kind: "event", with the fields of Fraud Label Feedback).
When to call it#
- Once a night, with every outcome of the last day or two. It is idempotent: items Gurdx already has come back
unchanged, so overlapping windows are fine. - Once, to backfill the past months of orders and their outcomes before Gurdx starts learning.
How it works#
Items are processed in order and independently. The response counts created, updated, unchanged, pending (outcomes waiting for their transaction) and failed items, and lists one result per item with its index. A bad item is reported with status: "error", its code and description, and does not stop the others.
Notes#
- Free: not counted against your quota, available on every plan. One call counts once toward the flood limit, whatever its size.
- More than 1,000 items returns error 132 (
too_many_feedback_items); a missing or emptyitemsreturns 131 (invalid_feedback), with HTTP 200. - Test mode validates every item and stores nothing.
Request#
https://gurdx.cretip.com/api/feedback/bulk
- Authenticate with the key parameter or an Authorization: Bearer header.
- Free — not counted against your quota.
- Available on: Free trial Standard Premium Pay-as-you-go
Parameters#
| Name | Type | Description |
|---|---|---|
items
required
body |
array |
Up to 1,000 feedback objects. Each has kind: payment (fields of Payment Outcome Feedback) or event (fields of Fraud Label Feedback). When kind is missing it is payment if the item has transaction_id or outcome.
|
Every method also accepts format, lang, mode, userID. See Options.
Code samples#
curl -X POST "https://gurdx.cretip.com/api/feedback/bulk" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"kind": "payment",
"transaction_id": "ORD-10492",
"outcome": "approved"
},
{
"kind": "payment",
"transaction_id": "ORD-9921",
"outcome": "chargeback",
"reason": "fraudulent"
},
{
"kind": "event",
"type": "ip",
"value": "203.0.113.42",
"label": "fraud"
}
]
}'
<?php
$payload = [
'items' => [
[
'kind' => 'payment',
'transaction_id' => 'ORD-10492',
'outcome' => 'approved',
],
[
'kind' => 'payment',
'transaction_id' => 'ORD-9921',
'outcome' => 'chargeback',
'reason' => 'fraudulent',
],
[
'kind' => 'event',
'type' => 'ip',
'value' => '203.0.113.42',
'label' => 'fraud',
],
],
];
$ch = curl_init('https://gurdx.cretip.com/api/feedback/bulk');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_API_KEY', 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$result = json_decode(curl_exec($ch), true);
if ($result['status'] !== 'success') {
error_log($result['code'].': '.$result['description']);
}
const res = await fetch('https://gurdx.cretip.com/api/feedback/bulk', {
method: 'POST',
headers: {
Authorization: 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"items": [
{
"kind": "payment",
"transaction_id": "ORD-10492",
"outcome": "approved"
},
{
"kind": "payment",
"transaction_id": "ORD-9921",
"outcome": "chargeback",
"reason": "fraudulent"
},
{
"kind": "event",
"type": "ip",
"value": "203.0.113.42",
"label": "fraud"
}
]
}),
});
const result = await res.json();
if (result.status !== 'success') {
console.error(result.code, result.description);
}
import requests
res = requests.post(
"https://gurdx.cretip.com/api/feedback/bulk",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"items": [
{
"kind": "payment",
"transaction_id": "ORD-10492",
"outcome": "approved",
},
{
"kind": "payment",
"transaction_id": "ORD-9921",
"outcome": "chargeback",
"reason": "fraudulent",
},
{
"kind": "event",
"type": "ip",
"value": "203.0.113.42",
"label": "fraud",
},
],
},
)
result = res.json()
if result["status"] != "success":
print(result["code"], result["description"])
Response#
Success#
{
"data": {
"received": 3,
"created": 2,
"updated": 0,
"unchanged": 1,
"pending": 1,
"failed": 0,
"results": [
{
"index": 0,
"kind": "payment",
"transaction_id": "ORD-10492",
"outcome": "approved",
"status": "applied",
"matched": 1,
"label": "created"
},
{
"index": 1,
"kind": "payment",
"transaction_id": "ORD-9921",
"outcome": "chargeback",
"status": "pending",
"matched": 0,
"label": "created"
},
{
"index": 2,
"kind": "event",
"type": "ip",
"value": "203.0.*.*",
"label": "fraud",
"status": "unchanged"
}
]
},
"status": "success",
"executionTime": 21
}Error#
Errors are delivered with HTTP 200 — always check the status field.
{
"status": "error",
"code": 101,
"type": "invalid_key",
"description": "The API Key is missing or invalid."
}Response fields#
| Name | Type | Description |
|---|---|---|
data.received |
integer |
Items received. |
data.created |
integer |
New labels. |
data.updated |
integer |
Labels whose value changed. |
data.unchanged |
integer |
Items identical to what Gurdx already had (safe to re-send). |
data.pending |
integer |
Payment outcomes kept until their transaction is scored. |
data.failed |
integer |
Items rejected; see their result. |
data.results |
array |
One result per item, in order, with its index. A rejected item has status: "error", code and description; the others are not affected.
|
Found a mistake? Tell us on the contact page. Contact