Statement Processing API

The Statement Processing API accepts payment processor statements and returns an analysis summary, authenticity score, period totals, and an Excel workup of the analyzed documents. All requests authenticate with a secret key. See Authentication.

Statement Processing Lifecycle

The statement processing workflow consists of three main steps:

  1. Initialize task (POST)
  2. Upload documents (PUTs)
  3. Processing result (GET or web hook)

Initialize Statement Processing Task

Initialize a statement processing session by posting the uploadFilenames of the documents that will be uploaded. Filenames do not need to be unique. The response will provide an array of objects with signed putUrl attributes where each file’s contents are sent in the next step.

Request

POST /statement/initialize
Authorization: sk_findustryai_kkkkkkkkkkkk_nnnn
{
  data: {
    uploadFilenames: [String]
  }
}
FieldTypeRequiredDescription
uploadFilenames Array of Strings (filenames) Yes File names to be uploaded (e.g., ["month-1.pdf", "month-2.pdf", "month-3.pdf"])

Response

{
  data: {
    id: String,
    putUrls: [
      {
        putUrl: String,
        uploadFilename: String,
      }
    ]
  }
}
FieldTypeDescription
id String (uuid) Identifier for the statement processing task
putUrls Array (see below) Endpoint-filename pairs for uploading
putUrl String (url) Signed URL endpoint for the document PUT operation. Connection to this endpoint is valid for five minutes
uploadFilename String (filename) Member from uploadFilenames

Document Upload

After initializing the task, send each file to the respective putUrl. These signed URLs are valid for five minutes.

PUT ${putUrl}
Content-Type: ${contentType}

Example using curl:

curl -X PUT -T file.pdf
"https://bucket.s3.amazonaws.com/file.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=3600&X-Amz-Signature=..."

Statement Results

Once the documents are uploaded the statement processor begins analyzing the document. The API response shows status: "processing" while the Agent is working. This process takes several minutes.

Request

GET /statement/:id
Authorization: sk_findustryai_kkkkkkkkkkkk_nnnn

Response

{
  data: {
    analysisSummary: String,
    authenticityScore: Number,
    documents: [{}],
    id: String,
    periodEnd: Date,
    periodStart: Date,
    processor: String,
    status: String,
    totalChargebackAmount: Number,
    totalFeesAmount: Number,
    totalNetAmount: Number,
    totalRefundAmount: Number,
    totalSalesAmount: Number,
  }
}
FieldTypeDescription
analysisSummary String Summary of the analysis and document authenticity
authenticityScore Number (0-100) Score reflecting how genuine the statement appears (higher = more authentic)
documents Array of Objects Per-document detail for each analyzed statement
id String (uuid) Identifier for the statement processing task
periodEnd Date (ISO 8601) Latest statement date
periodStart Date (ISO 8601) Earliest statement date
processor String Payment processor the statement belongs to, if identified during analysis
status String (enum) pending, queued, processing, complete, reopened, error
totalChargebackAmount Number (dollars) Chargebacks across all statements
totalFeesAmount Number (dollars) Fees across all statements
totalNetAmount Number (dollars) Net across all statements
totalRefundAmount Number (dollars) Refunds across all statements
totalSalesAmount Number (dollars) Sales across all statements

Web Hook

Web hooks may be registered as an alternative to polling the status. The event body will contain the same data attribute as the HTTP response, along with metadata and security headers for authentication.

Event Metadata

Along with the data attribute, the event body will contain a metadata attribute describing the web hook event.

{
  metadata: {
    attempt: Number,
    event: "statement:processed",
    id: String,
    timestamp: Number,
    type: "webhook"
  },
  data: {
    // …
  }
}
FieldTypeDescription
attempt Number (integer) Numeric counter of web hook delivery attempts beginning at 1
event String String value statement:processed
id String (uuid) Identifier for the web hook event. Does not change between retry attempts. Recommended as an idempotence token to prevent duplicate processing
timestamp Number (milliseconds) Timestamp for the web hook event attempt. Changes with each attempt
type String String value webhook

Acknowledgement

Web hooks interpret the HTTP response code as acknowledgement of receipt.

CodeResultDescription
2XX Success Mark delivered
401 Unauthorized Web hook failed authentication
429 Too many requests Delay next attempt. Retry with backoff
5XX Server error Retry with backoff. Unreachable hosts are treated as 504 Gateway Timeout
* Unknown error Client error, do not retry

Undeliverable Messages

Undeliverable messages will be reattempted for up to one hour. Messages that fail to deliver after one hour will be recorded for remediation. Findustry AI will reach out to discuss improving delivery rates.

Authentication

Web hook deliveries are signed with an HMAC signature in the X-Webhook-Signature header. See Web Hooks authentication.

Registration

Findustry AI will certify web hook endpoints and enable events by request.

Request Download

The statement processor produces an Excel workup of the analyzed documents. The API response shows status: "processing" while the Agent is working. This process takes several minutes. Once the download is ready it will return a getUrl.

Request

GET /statement/:id/download
Authorization: sk_findustryai_kkkkkkkkkkkk_nnnn

Response

Processing

{
  data: {
    id: String,
    status: "processing"
  }
}

Complete

{
  data: {
    id: String,
    getUrl: String
  }
}
FieldTypeDescription
id String (uuid) Identifier for the statement processing task
getUrl String (url) Signed URL for the document

Document Download

The download request will return a getUrl. This is a signed URL valid for five minutes.

Example downloading using curl:

curl -L -o file.pdf
"https://bucket.s3.amazonaws.com/file.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=3600&X-Amz-Signature=..."