API docs

Everything you need to connect T&P AITECH OCR to your systems

Authentication

Send your API key in the Authorization header on every request. Create keys on the API keys page in the dashboard.

Authorization: Bearer tnp_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Read a document

POSThttps://api.tnpaitech.com/v1/ocr

Send the file as multipart/form-data or JSON. The result comes back in the same request.

Parameters

NameTypeDescription
filefileThe document (PNG, JPG, WEBP, PDF) — multipart only
file_base64stringThe file as base64 or a data URL — JSON only
file_urlstring (https)An HTTPS link to the file — JSON only
mode"text" | "extract"text = full page (Markdown), extract = fields as JSON (default text)
template"auto" | "invoice" | "thai_id" | "passport" | "government_doc" | "custom"Template for extract mode (default auto)
fieldsJSON arrayFields to extract when template = custom, e.g. [{"name":"contract_no","description":"Contract number"}]
curl -X POST https://api.tnpaitech.com/v1/ocr \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@invoice.jpg" \
  -F "mode=extract" \
  -F "template=invoice"

Templates

Any documentauto

Extract every key-value pair automatically

items

Invoice / receiptinvoice

Seller, buyer, items, VAT, total

document_titledocument_numberissue_dateseller_nameseller_tax_idseller_branchseller_addressbuyer_namebuyer_tax_idbuyer_addressline_itemssubtotaldiscountvat_ratevat_amountwithholding_taxtotalcurrencypayment_terms

Thai ID cardthai_id

13-digit ID, name, birth date, address

id_numberprefix_thfirst_name_thlast_name_thprefix_enfirst_name_enlast_name_endate_of_birthreligionaddressissue_dateexpiry_datelaser_code

Passportpassport

MRZ, number, nationality, expiry

document_typeissuing_countrypassport_numbersurnamegiven_namesnationalitydate_of_birthsexplace_of_birthissue_dateexpiry_datepersonal_numbermrz_line1mrz_line2

Government lettergovernment_doc

Number, date, subject, recipient, signer

letter_numberissuing_agencydatesubjectrecipientreferencesenclosuressummarysigner_namesigner_positioncontact

Customcustom

Define your own fields

Example response

{
  "id": "ocr_3f9a1c0e2b7d4a5f6e8c9b10",
  "object": "ocr.result",
  "livemode": true,
  "mode": "extract",
  "template": "invoice",
  "pages": 1,
  "document_type": "Thai tax invoice / receipt",
  "fields": {
    "document_number": "INV-2026-0142",
    "issue_date": "2026-10-15",
    "seller_name": "บริษัท ตัวอย่าง จำกัด",
    "seller_tax_id": "0105555000000",
    "line_items": [
      {
        "description": "ค่าบริการ OCR",
        "quantity": 1,
        "unit_price": 1000,
        "amount": 1000
      }
    ],
    "vat_amount": 70,
    "total": 1070,
    "currency": "THB"
  },
  "warnings": [],
  "usage": {
    "credits_used": 1,
    "credits_remaining": 49,
    "latency_ms": 3120
  }
}

Error codes

{ "error": { "code": "insufficient_credits", "message": "This request needs 3 credit(s)" },
  "request_id": "ocr_3f9a1c0e2b7d4a5f6e8c9b10" }
400invalid_requestInvalid request
401unauthorizedThe API key is invalid or has been revoked
402insufficient_creditsNot enough credits. Please top up.
403account_suspendedThis account is suspended. Please contact support.
409idempotency_in_progressA request with this Idempotency-Key is still running. Wait and retry.
413file_too_largeThe file is too large
413too_many_pagesToo many pages
415unsupported_fileOnly PNG, JPG, WEBP and PDF are supported
422idempotency_mismatchThis Idempotency-Key was already used for a different request
429rate_limitedToo many requests. Please try again later.
429demo_limitYou've used today's free tries. Sign up free to keep going.
502ocr_failedCouldn't read the document. Please try again.
503not_configuredThe service isn't configured yet (contact the administrator)

Test mode

Create a Test key (tnp_test_…) on the API keys page to build your integration without spending credits. Files and parameters are validated as usual, but the response holds sample data and livemode: false.

Authorization: Bearer tnp_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Safe retries (idempotency)

Send an Idempotency-Key header (a unique value such as a UUID). After a timeout or dropped connection, resend the same request with the same key: you get the original result with Idempotent-Replayed: true and are not charged twice. Results are kept for 24 hours, only for requests that send this header. Reusing a key with a different file returns 422; retrying while the first request is still running returns 409.

curl -X POST https://api.tnpaitech.com/v1/ocr \
  -H "Authorization: Bearer $TNP_API_KEY" \
  -H "Idempotency-Key: 6f1c2a7e-4b8d-4f0a-9c3e-2d5b7a1e9f40" \
  -F "file=@invoice.pdf" -F "mode=extract" -F "template=invoice"

Rate limits and request IDs

Every response carries X-Request-Id: quote it when contacting support, or search for it on the Logs page. X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (unix seconds) show your quota; after a 429, wait for the number of seconds in Retry-After.

HTTP/1.1 429 Too Many Requests
X-Request-Id: ocr_3f9a1c0e2b7d4a5f6e8c9b10
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1793522940
Retry-After: 17

{ "error": { "code": "rate_limited", "message": "Limit is 60 requests per 60 seconds" },
  "request_id": "ocr_3f9a1c0e2b7d4a5f6e8c9b10" }

Limits

  • Direct uploads up to 4 MB (use file_url for files up to 20 MB)
  • Up to 30 PDF pages per request
  • 60 requests per minute per API key (see the X-RateLimit-* headers)
  • 1 credit per page, refunded automatically if the read fails