When teams in mainland China integrate an OCR API, the first instinct is usually to compare recognition rates and then call the endpoint. Only after launch do they discover that most of their time goes into the access layer: whether images upload reliably, whether the link works during evening peak hours, whether the bill is in USD or RMB, whether invoices can be booked, and how a batch job resumes after failing halfway.
OCR differs from chat APIs because the input is an image or PDF, so request bodies are larger, timeouts are more common, and retries more easily create duplicate charges. This article compares three routes — direct vendor access, a self-hosted proxy, and a China-based AI gateway — and focuses on image upload, rate limits, failover, and a launch checklist. Specific services and billing are subject to on-site model pricing and provider documentation.
Note: OpenAI, Claude, Gemini, Baidu AI Cloud, Tencent Cloud, Alibaba Cloud, and other names are trademarks of their respective owners; this article is for technical discussion only and has no affiliation or agency relationship with the vendors. Cross-border networking, data export, and payment settlement must comply with local laws and platform terms.
1. The three routes at a glance
Direct vendor access calls an OCR vendor's or model vendor's endpoint directly. With a mainland cloud vendor's OCR, the link and payment are already domestic, which is usually the simplest option; with an overseas vision model, you must handle cross-border networking, USD billing, and exchange rates yourself.
A self-hosted proxy deploys a reverse proxy or gateway on a compliant server to centralize authentication, logging, retries, and rate limits. It offers strong control, but you own the server, certificates, upgrades, and on-call duty. OCR also requires adjusting request-body limits and timeouts, or large images are easily truncated at the proxy layer.
A China-based AI gateway provides an OpenAI-compatible entry point and RMB settlement, usually with a console, usage statistics, and invoices. Integration cost is low and it simplifies multi-model management; confirm the service entity, data terms, quota rules, and incident-response process.
| Dimension | Direct vendor access | Self-hosted proxy | China-based AI gateway |
|---|---|---|---|
| Network and access | Short path for mainland vendors; cross-border for overseas models | Line can be chosen; you operate it | Domestic entry, usually ready to use |
| Image upload | Limited by vendor request-body and format rules | Proxy limits must be adjusted in sync | Depends on the gateway's body and timeout settings |
| Payment and invoices | RMB for mainland vendors; USD for overseas models | Depends on the account and server entity | RMB settlement, usually with invoices |
| Batch and rate limits | Constrained by vendor QPS, concurrency, and quota | Queues are possible, but upstream limits remain | Depends on gateway quotas, scheduling, and retries |
| Data boundary | You assess cross-border transfer and terms | You are responsible for data location | Review provider terms and qualifications |
| Operations cost | Medium, mainly network and accounts | High: server, certificates, monitoring | Low, centrally managed console |
| Model coverage | Mostly a single vendor | You can extend it yourself | Usually covers multiple vendors |
2. Network and image upload: solve 413 and timeouts first
OCR request bodies are much larger than text requests. A 3 MB image becomes about 4 MB after Base64 encoding, roughly one third larger. If the endpoint only accepts Base64, the client, reverse proxy, and gateway must all raise their request-body limits. Common failures are often not "bad recognition" but 413 responses, connection resets, timeouts, and truncated responses.
A few practical recommendations:
- When the endpoint supports a URL or presigned address, prefer sending an image by URL to reduce the request body; confirm the link stays valid until recognition finishes and requires no login session.
- Compress to a resolution the business can accept, but do not overdo it; small text, stamps, handwriting, and table lines are sensitive to clarity. Compress against both long-edge and file-size thresholds, and keep the original for review.
- Rotate according to EXIF orientation before uploading, so a sideways page does not scramble recognition order.
- Adjust
client_max_body_size,proxy_read_timeout, andproxy_send_timeoutat the proxy layer as well; do not change only application-side timeouts. - For multi-page PDFs, prefer an asynchronous task endpoint instead of putting the whole file into one synchronous request.
If the provider fetches an image URL, confirm the address is publicly reachable, requires no login session, and has a signature validity period that covers queueing time.
3. Payment, contracts, and invoices
A common blocker for mainland teams is the paying entity. Personal-card top-ups, third-party payment, and inconsistent reimbursement documents often leave finance unable to book the expense. Before choosing a route, clarify who signs the contract, the settlement currency, the invoice type, the prepayment validity period, and the refund rules.
For usage-based billing, also confirm the bill basis: per image, per PDF page, per request, or per token; whether failed requests count; whether retries are billed again; and whether usage can be split by project or key. Put these into the procurement comparison table and test with the same image batch to estimate real cost. Specific fees are subject to model pricing and the contract.
4. Rate limits, concurrency, and batch jobs
OCR endpoints are usually constrained simultaneously by QPS, concurrency, per-image size, PDF page count, and a daily account quota. A 429 does not necessarily mean a service incident; it may simply be a momentary concurrency spike. Design batch recognition in this order:
- Compute a SHA-256 hash for each image or PDF as an idempotency key, and check the local result table before deciding whether to submit.
- Split tasks according to endpoint limits: set separate thresholds for per-image size, pages per request, and concurrency.
- Start with low concurrency, for example 2 to 4 workers, and raise it gradually after observing the 429 rate and P95 latency.
- Apply exponential backoff with jitter to 429 and transient 5xx errors; do not retry 401, 403, or parameter errors — fix the configuration first.
- Record task_id, submission time, status, and result address for async tasks, and persist result files promptly because result links often expire.
- At the end of each batch, count successes, failures, billed images, and elapsed time, and move failed samples into a separate rerun queue.
- After the full run, sample and review results manually, and reconcile the number of records written against the number of source files.
5. Retries, idempotency, and failover
Make requests idempotent before retrying, or one network hiccup can become two charges and two records. The example marks requests with an image hash and backs off on retryable errors:
import base64
import hashlib
import os
import time
from openai import OpenAI
client = OpenAI(
api_key=os.environ["ZSQH_API_KEY"],
base_url=os.environ["ZSQH_BASE_URL"],
timeout=90.0,
max_retries=0,
)
def ocr_image(path, model, attempts=4):
raw = open(path, "rb").read()
key = hashlib.sha256(raw).hexdigest()
data_url = "data:image/jpeg;base64," + base64.b64encode(raw).decode()
for i in range(attempts):
try:
resp = client.chat.completions.create(
model=model,
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "Read all text in the image and output it in the original order."},
{"type": "image_url", "image_url": {"url": data_url}},
],
}],
)
return key, resp.choices[0].message.content
except Exception as exc:
if i == attempts - 1:
raise
wait = min(2 ** i, 30) + 0.5 * (i + 1)
print(key[:8], type(exc).__name__, "retry in", wait)
time.sleep(wait)
key, text = ocr_image("invoice.jpg", os.environ["VISION_MODEL"])
print(key[:12], len(text))
Failover has an easily overlooked boundary: outputs from different OCR engines cannot be mixed directly. Traditional OCR returns text and coordinates, while a vision LLM returns natural language or JSON, and field names and coordinate systems may differ. Before switching, fix a set of real samples and compare character accuracy, field accuracy, and structured-output success rate; parsing code and review workflows must change together, not just the model name.
6. Pre-launch verification checklist
- Link: stress-test large images, multi-page PDFs, and evening peak periods separately, and record the rates of 413, timeouts, and 5xx.
- Accuracy: use 50 to 100 real images covering clear, blurry, tilted, handwritten, tabular, and multi-column layouts.
- Usage: check whether usage tokens or image counts in responses match the backend bill, and whether retries are charged twice.
- Rate limits: confirm that the concurrency cap, 429 rate, and post-backoff success rate are acceptable.
- Data: determine whether images contain personal information or trade secrets, and whether the provider's retention, logging, and deletion policies are clear.
- Exit: can keys be rotated, can the balance be refunded, and are the old service and rollback path retained?
If any item is unclear, run a small traffic trial first; do not switch production traffic over directly.
7. Choose by constraints
The selection order is: whether network and payment can stay stable long term, whether a fixed egress and audit trail are required, and only then model coverage and billing capabilities. If a mainland cloud OCR workflow is smooth, connect directly; if you use overseas vision models without staff for cross-border operations, evaluate a China-based gateway. If you need a unified entry point and RMB settlement, create a test key at ZSQH AI Gateway, get a small image batch working first, then scale up; see model pricing for billing.
FAQ
Is direct access to an overseas OCR endpoint from mainland China stable?
It depends on the local egress, time of day, target region, and account quota; there is no blanket answer. Observe real images and real concurrency for several days, record the error rate and P95 latency, and compare with a gateway option rather than concluding from one successful request.
Should images be uploaded as Base64 or by URL?
Base64 is simple and direct for small images; for large images, multi-page PDFs, or high-concurrency scenarios, prefer a URL or a presigned object-storage address, which significantly reduces the request body. Either way, confirm the endpoint's size limits, format requirements, and link validity.
How do I resume an interrupted OCR batch?
Use a content hash as the idempotency key, persist results batch by batch, and rerun only the missing parts. Before rerunning, reconcile the number of records already written against the source file count, so you avoid both duplicate writes and treating a half-finished batch as complete.
Will the result format change after switching OCR services?
Usually yes. Different engines may use different field names, coordinate systems, confidence scores, and error structures, and structured output requires schema validation again. During migration, retain old results for a period and compare old and new output on fixed samples.
Can invoices and usage be split by project?
It depends on the provider. Before signing, confirm whether usage can be exported by project, key, or model, whether the bill basis includes failed and retried requests, and whether invoice content can match procurement requirements.
Related reading:
