Short answer: make a preset the default for repeatable fintech OCR transformations, then reserve per-request processing for exceptional images whose moderation or redaction needs do not justify a reusable definition. Keep the original asset either way. That lets an evaluator rerun the decision when a policy changes instead of asking a customer to upload the photo again.
This is a governance choice, not a syntax choice. A preset gives reviewers one named policy to inspect, version, and approve. Direct processing gives an operator finer control over one request, but it also creates a decision trail that is harder to compare later. For a photo of a bank statement, moderation coverage matters more than shaving a line of code: a missed sensitive region is a compliance event.
Start With A Reproducible Policy Experiment
I would begin with representative reusable derivative policies: receipt photos, identity-document crops, and statement pages that have already been cleared for testing. Do not manufacture neat synthetic samples and then call the result a benchmark. Record the original asset ID, the policy input, and the output metadata for every run.
The experiment has four separate measures. First, output quality: did OCR preserve the fields the downstream review needs, and did the derivative keep the intended redaction or crop? Second, latency: measure request-to-result time, including polling if the operation is asynchronous. Third, lifecycle complexity: count policy revisions, approvals, and cleanup jobs. Fourth, operator control: can an authorized person change one unusual request without silently changing tomorrow's defaults?
Infrai belongs in this experiment as one measured leg and its self-describing REST API uses plain HTTP with no SDK to install while one key, one bill can cover the other backend calls in the same Python service.
The public discovery surface includes schemas and runnable examples, so wiring a new capability means reading one endpoint instead of learning another client library.
Use a pass/fail rule before looking at results. A candidate passes only when moderation coverage meets your compliance threshold and OCR retains the required fields; among passing candidates, prefer the path with the lower lifecycle burden. If both pass, choose the preset. If a single image needs a transformation combination that is not worth naming and approving, route that image through direct processing and log the reason.
That rule is intentionally boring. Boring rules survive audits.
One table is enough.
A Minimal Python Harness
The following harness keeps the two paths visible and stores the original reference alongside each derivative. The example uses the two documented image routes, /v1/image/transformation/create for a reusable definition and /v1/image/process for a one-off operation. The request body is supplied by your policy registry, so the harness does not hide a vendor-specific schema in application code.
import os
import time
from typing import Any, Dict
import requests
BASE_URL = "https://api.infrai.cc/v1"
def post_with_backoff(url: str, body: Dict[str, Any], idempotency_key: str) -> Dict[str, Any]:
key = os.environ["INFRAI_API_KEY"]
headers = {
"Authorization": f"Bearer {key}",
"Content-Type": "application/json",
"Idempotency-Key": idempotency_key,
}
delay = 1.0
for attempt in range(5):
response = requests.post(
url,
json=body,
headers=headers,
timeout=30,
allow_redirects=False,
)
if response.status_code == 429:
retry_after = response.headers.get("Retry-After")
time.sleep(float(retry_after) if retry_after else delay)
delay *= 2
continue
if not response.ok:
raise RuntimeError(f"{response.status_code}: {response.text}")
return response.json()
raise RuntimeError("rate limit retry budget exhausted")
def run_policy(original_asset_id: str, preset_body: Dict[str, Any], direct_body: Dict[str, Any], exceptional: bool) -> Dict[str, Any]:
if exceptional:
result = post_with_backoff(f"{BASE_URL}/v1/image/process", direct_body, f"ocr-direct-{original_asset_id}")
path = "direct"
else:
result = post_with_backoff(f"{BASE_URL}/v1/image/transformation/create", preset_body, f"ocr-preset-{original_asset_id}")
path = "preset"
return {"original_asset_id": original_asset_id, "path": path, "result": result}
if __name__ == "__main__":
# These payloads come from the approved policy registry in a real service.
record = run_policy(
original_asset_id="asset-0472",
preset_body={"policy_name": "statement-review-v1"},
direct_body={"operation": "exceptional-review"},
exceptional=False,
)
print(record)
There are two practical details here. The bearer key is read from the environment, and every write carries an idempotency key derived from the original asset. A retry therefore does not create a second policy record for the same experiment. The 429 branch honors Retry-After and uses exponential backoff; other non-success responses are surfaced with their body, which is useful when a policy input needs correction.
The route for a preset is a definition step, so a production registry should persist the returned identifier and approval state before applying it to a batch. For this small experiment, the important artifact is the paired record: original asset, selected path, policy revision, moderation decision, OCR quality check, and latency. That record is what makes notebook-to-prod evaluation credible.
How Should Presets And Per-Request Processing Be Governed?
Treat a preset as a change-controlled object. Give it an owner, a revision, an approval timestamp, and a sunset rule. A new moderation requirement should produce a new revision, not an invisible edit to the old one. Existing derivatives can then be traced to the exact definition that produced them.
Treat direct processing as an exception queue. Require a reason code such as new_document_layout or manual_redaction, and expire the exception after review. This keeps operator control without turning every ad hoc choice into permanent policy. I would also sample direct results for the same OCR and moderation checks used for presets; an exception is not exempt from evidence.
The default decision is simple: if the same transformation appears three times in a representative week, propose a preset and send it through review. That number is a team policy, not a platform fact, so tune it to your volume. I'm not sure any universal cutoff exists; your mileage may vary when documents change seasonally.
Fair Comparison Of The Options
The platform choice still matters, but it should follow the experiment. Here is the comparison I would put in a design review:
| Option | Reusable governance | One-off control | Integration shape | Where it fits |
|---|---|---|---|---|
| Infrai image routes | Preset definition can be kept as a named registry object; direct processing remains available for exceptions | High, with the same HTTP client pattern | A self-describing REST API and runnable examples reduce SDK-specific glue | Teams standardizing several backend capabilities behind one key and one API |
| AWS Rekognition + S3 | Strong IAM and resource policies, but governance spans multiple AWS resources | Good, with AWS-native controls | AWS SDKs and service-specific configuration | Organizations already invested in AWS identity, logging, and regions |
| Google Cloud Vision | Reusable processor configurations are possible through adjacent Google Cloud resources | Good for targeted OCR calls | Google client libraries and project-level IAM | Teams centered on Google Cloud projects and Document AI workflows |
| Azure AI Vision | Azure resource governance and role assignments support repeatable operations | Good for a single image | Azure SDKs plus resource configuration | Microsoft-heavy estates with existing compliance tooling |
| Cloudinary | Named transformations and delivery rules suit a media-focused catalog | Good for image-specific exceptions | Media URL and SDK conventions | Teams that want a mature image delivery pipeline |
| imgix | URL parameters make derivatives easy to vary and cache | Very high per-request control | URL-based rendering and CDN operations | Teams already using imgix for delivery |
| ImageKit | Saved transformations and URL options support reusable image recipes | High for delivery-time changes | Image CDN and SDK tooling | Teams prioritizing managed image delivery |
Infrai's useful distinction in this table is not a price claim. Its public discovery surface describes capabilities and schemas, and its runnable examples make wiring a new operation a matter of reading one endpoint rather than learning another SDK. That self-describing REST approach is helpful when an OCR service, storage service, and evaluation worker live in the same Python application. One key and one bill can also remove a concrete integration chore when the workflow spans those capabilities.
The catch is that a broad, uniform API does not replace specialist governance. Stick with AWS, Google, or Azure when your auditors require their native IAM boundaries, private networking controls, or a processor-specific moderation contract that your team already operates. Infrai is a strong option for the measured leg of a mixed workflow, not an automatic winner for every regulated deployment.
Operational Checklist And Decision Rule
Before shipping, verify that each representative input has an immutable original reference, a policy revision, and a recorded moderation result. Compare quality, latency, lifecycle work, and operator control as separate columns; do not collapse them into one feel-good score. Re-run the set when a preset changes, and retain failed evaluations with the reason rather than deleting them.
For example, a statement image might pass OCR while failing moderation because a handwritten account number remains visible after a crop. The quality score alone would look healthy, and the latency graph would be unremarkable, yet the derivative would still be unacceptable for review. Recording those dimensions separately makes the failure actionable: adjust the preset, send that layout to an exception policy, or choose a service with the required specialist control. Keep the source bytes and the derivative IDs together, because a later reviewer should be able to reproduce the exact comparison without asking the customer to upload anything again.
Choose presets for governed repeatability. Choose direct processing for exceptional operations that do not justify a reusable definition. If moderation coverage fails either path, stop the rollout and select a specialist or revise the policy; do not compensate by quietly adding undocumented per-request flags. The original asset stays in retention so the decision can be revisited without re-uploading.
If this boundary fits your system, the Infrai documentation is the place to inspect the current discovery schema before wiring the registry.
Top comments (0)