Skip to main content

Overview

The Kibo Redaction API implements a two-phase workflow for processing GDPR right-to-erasure requests (and similar data subject deletion obligations). The two phases are:
  1. Create a draft report — Kibo scans the tenant’s data for all PII associated with the subject and returns a report listing every affected record. No data is modified at this stage.
  2. Execute the redaction — After reviewing the draft, you trigger the irreversible redaction that overwrites or removes the identified PII.
This separation exists to provide an auditable review step before any destructive action is taken. Your compliance team can inspect exactly what will be redacted before committing.

How This Domain Fits Into Kibo

A single data subject’s PII can exist across many parts of the Kibo platform. The redaction engine covers:
Entity typeWhat is redacted
OrdersBilling/shipping addresses, contact details, custom attributes
PaymentsPayment method identifiers attached to orders
CheckoutsIn-progress or abandoned checkout PII
ReturnsReturn contact and address details
WishlistsWishlist owner identity
ShipmentsRecipient contact and address details
Customer accountThe account record itself (identified by customerAccountId)
The two-phase design lets you audit the scope of a deletion request before executing it — important both for GDPR compliance and for avoiding accidental data loss.

Prerequisites

  • Kibo API credentials (client ID and shared secret) with access to the platform/data namespace
  • The customerAccountId (integer) or userId (string) of the data subject whose data must be erased
  • An understanding of any custom attribute FQNs attached to orders, customers, returns, or shipments for your tenant, if you need those included in the redaction

The Two-Phase Workflow

Phase 1 — Create a Redaction Report (Draft)

Endpoint: POST /platform/data/redaction/reportAPI reference This call scans the tenant’s data and returns a draft report. No data is modified.

Request body

{
  "customerAccountId": 4820193,
  "userId": null,
  "attributeFqns": {
    "order": ["tenant~gdpr-consent-date"],
    "customer": ["tenant~marketing-opt-in"],
    "return": null,
    "shipment": null
  },
  "clearDataNodes": {
    "orders": false,
    "checkouts": true,
    "shipments": false
  }
}
Field descriptions:
FieldTypeDescription
customerAccountIdintegerThe Kibo customer account ID of the data subject. Required if userId is not provided.
userIdstringThe user ID of the data subject. Required if customerAccountId is not provided.
attributeFqns.orderstring[]Fully-qualified names of custom order attributes to include in the redaction scope.
attributeFqns.customerstring[]Fully-qualified names of custom customer attributes to include.
attributeFqns.returnstring[]Fully-qualified names of custom return attributes to include.
attributeFqns.shipmentstring[]Fully-qualified names of custom shipment attributes to include.
clearDataNodes.ordersbooleanIf true, wipes the entire order data node rather than field-level PII only.
clearDataNodes.checkoutsbooleanIf true, wipes the entire checkout data node.
clearDataNodes.shipmentsbooleanIf true, wipes the entire shipment data node.

Example response

{
  "reportId": "a3f9c2d1-4e7b-4f8a-b2c3-9d0e1f2a3b4c",
  "schemaVersion": 1,
  "tenantId": 1000000,
  "status": "Draft",
  "subject": {
    "customerAccountId": 4820193,
    "userId": null,
    "resolvedEmailAddresses": ["jane.doe@example.com"]
  },
  "auditInfo": {
    "createBy": "840065bee668435b9d5346e60e6b1f88",
    "createDate": "2026-03-19T14:00:00Z",
    "updateBy": null,
    "updateDate": null
  },
  "request": {
    "correlationId": "corr-7f3a9b21",
    "attributeFqns": {
      "order": ["tenant~gdpr-consent-date"],
      "customer": ["tenant~marketing-opt-in"],
      "return": null,
      "shipment": null
    },
    "clearDataNodes": {
      "orders": false,
      "checkouts": true,
      "shipments": false
    }
  },
  "createdAt": "2026-03-19T14:00:00Z",
  "executionStartedAt": null,
  "executionCompletedAt": null,
  "affectedEntities": {
    "customerAccountId": 4820193,
    "orders": { "count": 3, "ids": ["1ab0edd566b26c0001ce7f1f000186e3", "2bc1fee677c37d1102df8g2g111297f4", "3cd2gff788d48e2213eg9h3h222308g5"] },
    "payments": { "count": 2, "ids": ["af6f5fd885de41c589f4b363012f78ef", "be7g6ge996ef52d69ag5c474123g89fg"] },
    "checkouts": { "count": 2, "ids": ["1ab0edd566b26c0001ce7f1f000186e3", "2bc1fee677c37d1102df8g2g111297f4"] },
    "returns": { "count": 1, "ids": ["3cd2gff788d48e2213eg9h3h222308g5"] },
    "wishlists": { "count": 1, "ids": ["4de3hgg899e59f3324fh0i4i333419h6"] },
    "shipments": { "count": 3, "ids": ["802", "803", "804"] }
  },
  "operationLog": null,
  "errorSummary": null
}
The key field to note is status: "Draft". The report has been created and the affected entities have been identified, but nothing has been changed yet.

Phase 2 — Review the Draft Report

Endpoint: GET /platform/data/redaction/report/{reportId}API reference Retrieve the draft report and verify the scope before committing to the redaction.
GET /platform/data/redaction/report/a3f9c2d1-4e7b-4f8a-b2c3-9d0e1f2a3b4c
Review the affectedEntities object carefully:
  • orders.count / orders.ids — the orders that will have PII removed
  • payments.count / payments.ids — payment records linked to those orders
  • checkouts.count / checkouts.ids — any checkout records found
  • returns.count / returns.ids — return records
  • wishlists.count / wishlists.ids — wishlist records
  • shipments.count / shipments.ids — shipment records
  • customerAccountId — the resolved account ID of the subject
Confirm that status is "Draft" before proceeding to execution. A report with status: "Executed" cannot be executed again.

Phase 3 — Execute the Redaction

Endpoint: POST /platform/data/redaction/execute/{reportId}API reference
Execution is irreversible. Once you call this endpoint the identified PII is permanently removed or overwritten. There is no undo. Ensure the draft report has been reviewed and approved before proceeding.
POST /platform/data/redaction/execute/a3f9c2d1-4e7b-4f8a-b2c3-9d0e1f2a3b4c
This endpoint has no request body. The reportId in the path identifies which draft to execute.

Example response

{
  "reportId": "a3f9c2d1-4e7b-4f8a-b2c3-9d0e1f2a3b4c",
  "schemaVersion": 1,
  "tenantId": 1000000,
  "status": "Executed",
  "subject": {
    "customerAccountId": 4820193,
    "userId": null,
    "resolvedEmailAddresses": ["jane.doe@example.com"]
  },
  "createdAt": "2026-03-19T14:00:00Z",
  "executionStartedAt": "2026-03-19T14:05:00Z",
  "executionCompletedAt": "2026-03-19T14:05:03Z",
  "affectedEntities": {
    "customerAccountId": 4820193,
    "orders": { "count": 3, "ids": ["1ab0edd566b26c0001ce7f1f000186e3", "2bc1fee677c37d1102df8g2g111297f4", "3cd2gff788d48e2213eg9h3h222308g5"] },
    "payments": { "count": 2, "ids": ["af6f5fd885de41c589f4b363012f78ef", "be7g6ge996ef52d69ag5c474123g89fg"] },
    "checkouts": { "count": 2, "ids": ["1ab0edd566b26c0001ce7f1f000186e3", "2bc1fee677c37d1102df8g2g111297f4"] },
    "returns": { "count": 1, "ids": ["3cd2gff788d48e2213eg9h3h222308g5"] },
    "wishlists": { "count": 1, "ids": ["4de3hgg899e59f3324fh0i4i333419h6"] },
    "shipments": { "count": 3, "ids": ["802", "803", "804"] }
  },
  "operationLog": [
    {
      "timestamp": "2026-03-19T14:05:00Z",
      "phase": "Execution",
      "store": "main",
      "entityType": "Order",
      "entityId": "1ab0edd566b26c0001ce7f1f000186e3",
      "operation": "RedactPii",
      "status": "Success",
      "recordsAffected": 1,
      "durationMs": 42,
      "errorMessage": null
    },
    {
      "timestamp": "2026-03-19T14:05:01Z",
      "phase": "Execution",
      "store": "main",
      "entityType": "CustomerAccount",
      "entityId": "4820193",
      "operation": "RedactPii",
      "status": "Success",
      "recordsAffected": 1,
      "durationMs": 38,
      "errorMessage": null
    }
  ],
  "errorSummary": null
}
After execution, status changes to "Executed", executionCompletedAt is populated, and operationLog contains one entry per operation performed.

Reading the operation log

FieldDescription
timestampWhen this individual operation ran
phaseProcessing phase (e.g., "Execution")
storeThe data store or context within the tenant
entityTypeThe type of record affected (e.g., "Order", "CustomerAccount")
entityIdThe ID of the specific record
operationThe action taken (e.g., "RedactPii")
status"Success" or "Failed" for this individual operation
recordsAffectedNumber of records modified by this operation
durationMsTime taken in milliseconds
errorMessagePopulated only on failure; describes what went wrong
If any entries have status: "Failed", check errorMessage for details and review errorSummary on the report for a rolled-up description.

Listing and Auditing Reports

Endpoint: GET /platform/data/redaction/reportAPI reference Use this endpoint to retrieve a paginated list of reports — useful for auditing which requests have been fulfilled and which drafts are awaiting execution.

Query parameters

ParameterTypeDescription
statusstringFilter by report status: Draft or Executed
fromdate-timeReturn only reports created at or after this timestamp (ISO 8601)
todate-timeReturn only reports created at or before this timestamp (ISO 8601)
pageintegerPage number (1-based)
pageSizeintegerNumber of results per page

Example request

GET /platform/data/redaction/report?status=Draft&page=1&pageSize=20

Example response

{
  "startIndex": 0,
  "pageSize": 20,
  "items": [
    {
      "reportId": "a3f9c2d1-4e7b-4f8a-b2c3-9d0e1f2a3b4c",
      "schemaVersion": 1,
      "tenantId": 1000000,
      "status": "Draft",
      "subject": {
        "customerAccountId": 4820193,
        "userId": null,
        "resolvedEmailAddresses": ["jane.doe@example.com"]
      },
      "createdAt": "2026-03-19T14:00:00Z",
      "executionStartedAt": null,
      "executionCompletedAt": null,
      "errorSummary": null
    }
  ]
}
Note that the list response returns RedactionReportSummaryResponse objects, which do not include affectedEntities, request, or operationLog. To get those fields, retrieve the individual report by ID.

Field Reference

Key fields on RedactionReportResponse:
FieldTypeDescription
reportIdstringUnique identifier for this redaction report
statusstring"Draft" before execution, "Executed" after
tenantIdintegerThe Kibo tenant this report belongs to
subject.customerAccountIdintegerResolved customer account ID of the data subject
subject.resolvedEmailAddressesstring[]Email addresses resolved from the subject’s account
affectedEntitiesobjectCounts and IDs of all records that will be / were redacted
operationLogarrayPer-record operation results; populated only after execution
createdAtdate-timeWhen the draft report was created
executionStartedAtdate-timeWhen execution began (null on Draft)
executionCompletedAtdate-timeWhen execution finished (null on Draft)
errorSummarystringHigh-level error description if any operations failed

Troubleshooting

Empty affectedEntities on a draft report The subject identifier provided (customerAccountId or userId) did not match any records. Verify the ID is correct for your tenant. Note that customerAccountId is a tenant-scoped integer, not a global Kibo user ID. 400 or 422 when creating a report Ensure you are providing at least one of customerAccountId or userId. Providing neither, or providing an attributeFqns array with invalid FQN strings, will result in a validation error. Attempting to execute an already-executed report Once a report has status: "Executed", calling POST /platform/data/redaction/execute/{reportId} again will return an error. Each data subject erasure request requires a new draft report. Partial failures in the operation log If some operationLog entries show status: "Failed", the redaction completed partially. Records that failed were not redacted. Review each failed entry’s errorMessage. You may need to create and execute a new report to retry the affected records, or investigate the underlying data integrity issue before retrying.