Skip to main content

Photon Commerce

Photon SDK for Python

The official Python SDK for Photon Commerce — extract structured data from invoices, receipts, and financial documents.

PyPI SOC 2 GDPR Accuracy Languages Python 3.10+

Website · API Docs · Pricing · Free Trial


Overview

Photon Commerce extracts standardized data from documents (PDFs, images, Word, HTML, and emails) with 99%+ accuracy, combining AI processing with human verification. Results come back as JSON with 100+ standardized fields across amounts, vendor, bill-to, metadata, line items, and payment details, in 25+ languages.

This SDK wraps that API in a fully typed Python client: extract a document in a single call, read the result as typed attributes, and correct it in place.

Installation

pip install photon-sdk

Quick Start

from photon import PhotonClient

client = PhotonClient(
    client_id="YOUR_CLIENT_ID",
    username="YOUR_USERNAME",
    api_key="YOUR_API_KEY",
    password="YOUR_PASSWORD",
    secret_key="YOUR_SECRET_KEY",
)

# Submit a document and wait for the extracted result
invoice = client.extract("invoice.pdf", doctype="invoice")

print(invoice["Vendor_Name"])  # Acme Supplies
print(invoice["Invoice_Number"])  # INV-2024-00842
print(invoice["Total"])  # 4750.00
print(invoice["Currency_Code"])  # USD

Get free sandbox credentials (20 complimentary extractions, no payment info required) at app.photoncommerce.com.

Extracted Fields

Category Fields
Amounts Balance due, total, subtotal, tax, discounts, currency
Vendor Name, address, phone, email, tax ID
Bill To Name, address, phone, email, tax ID
Metadata Invoice number, date, due date, PO number
Line Items Description, quantity, unit price, amount, SKU, GL code
Payment Payment terms, bank details, IBAN, routing number

Usage

Credentials

Pass the five credentials to PhotonClient, or set them as environment variables and use PhotonClient.from_env():

export PHOTON_CLIENT_ID=...
export PHOTON_USERNAME=...      # your account email
export PHOTON_API_KEY=...
export PHOTON_PASSWORD=...
export PHOTON_SECRET_KEY=...
export PHOTON_ENVIRONMENT=sandbox   # or "production"
from photon import PhotonClient

with PhotonClient.from_env() as client:
    ...

Extract a document

extract() uploads the document and polls until the result is ready:

invoice = client.extract("invoice.pdf", doctype="invoice", timeout=600)

invoice.vendor_name  # "Acme Supplies Ltd"
invoice.total  # Decimal("1397.50")
invoice.due_date  # datetime.date(2026, 11, 18)
for line in invoice.line_items:
    print(line.line, line.description, line.qty, line.amount)

invoice["Vendor_Name"]  # the API's own field names work too
invoice.raw  # the untouched payload
invoice.to_dict()  # typed fields as a dict; to_json() for JSON

A document can be a path, an open binary file, raw bytes, or a public URL (client.extract(url="https://...")).

Invoices and receipts (doctype="invoice" / "receipt-expense") return a typed InvoiceDocument: amounts are exact Decimals, ISO dates are datetime.date, and anything absent reads as None. Every other doctype (check, remittance, bol, statement, ...) returns a RawDocument, read by the API's field names: doc["payerName"].

Submit now, retrieve later

Processing can take from seconds (AI extraction) to hours (human verification), so you can also split the two steps:

submission = client.submit("invoice.pdf", doctype="invoice", webhook_url="https://example.com/hook")
# ... later, or once the webhook fires:
invoice = client.retrieve(submission.photon_key, doctype="invoice")

retrieve() raises NotReadyError while the document is still processing. extract(..., timeout=None) submits without waiting and returns the Submission.

Correct extracted data

Updates use the API's field names, exactly as the result spells them:

key = invoice.photon_key

client.update_fields(key, {"Vendor_Name": "Acme Supplies Ltd", "Total": "1397.50"})
client.update_line_item(key, 2, {"QTY": 3, "Amount": "225.00"})
client.add_line_item(key, {"Line": 3, "Description": "Shipping", "QTY": 1, "Amount": "25.00"})
client.delete_line_item(key, 3)

Errors

Every error raised by the SDK is a PhotonError carrying status_code, message and the response body:

Exception When
AuthenticationError Credentials rejected (401)
QuotaExceededError The account's allowance is used up
InvalidRequestError The request or file was rejected (bad file, unknown key, invalid line item, ...)
NotReadyError The document is still processing
ExtractionTimeoutError extract() gave up waiting; retrieve later by photon_key
PhotonConnectionError The API could not be reached
APIError Any other unsuccessful response
ConfigurationError Missing credentials or an unknown environment

Invalid arguments raise ValueError before anything is sent.

Retries

Server errors (5xx) and network failures are retried up to max_retries times (default 3) with exponential backoff. Requests that could take effect twice — submitting a document, adding or deleting a line item — are only retried when the connection itself failed. 4xx errors are never retried.

client = PhotonClient.from_env(max_retries=5, backoff_factor=1.0, timeout=60)

Retries are logged at DEBUG on the photon logger; credentials and document keys are never logged.

Processing Times

Account Type Turnaround
Trial Up to 24 hours (human verification included)
Production 5 minutes to 24 hours (human verification included)
AI Extraction Seconds (contact support@photoncommerce.com to activate)

Authentication

The SDK sends your credentials as four headers on every request. Free sandbox credentials are available at no cost.

CLIENT-ID:     your-client-id
AUTHORIZATION: apikey your-username:your-api-key
PASSWORD:      your-password
SECRET-KEY:    your-secret-key

Sample Response

{
  "data": {
    "Total": 22001.38,
    "Balance_Due": 22001.38,
    "Subtotal": 22001.38,
    "Tax": 0,
    "Currency_Code": "USD",
    "Document_Type": "Invoice",
    "Invoice_Number": "2/02/2021",
    "Date": "2021-02-03",
    "Due_Date": "2021-02-10",
    "Vendor_Name": "TUNEGO, INC.",
    "Vendor_Address": "32505 Anthem Village Drive, Suite E283, Henderson, NV 89052",
    "Bill_To_Name": "MOBILE REALITY sp. z o. o",
    "Bill_To_Address": "03-901 Warszawa, Poland",
    "Line_Items": [
      {
        "Line": 1,
        "Description": "React.JS frontend development",
        "QTY": 160,
        "Unit": "hrs",
        "Price": 42.5,
        "Amount": 6800
      }
    ],
    "Pages": 1,
    "photon_key": "data/johndoe@abc.com/2026-01-05/23-40-12_TuneGO.json"
  },
  "message": "success",
  "status": "success"
}

Development

git clone https://github.com/Photon-Commerce/photon-sdk-python.git
cd photon-sdk-python
pip install -e ".[dev]"

pytest --cov          # run tests with coverage
ruff check .          # lint
ruff format --check . # formatting
mypy                  # type-check

Releasing

Bump __version__ in src/photon/_version.py, add the version to CHANGELOG.md, merge to main, then push a matching tag:

git tag v0.1.0 && git push origin v0.1.0

The release workflow builds the package, installs it in a clean environment, publishes it to PyPI and creates the GitHub release.

License

MIT

Metadata

Release files for photon-sdk 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for photon-sdk 0.1.0
File Size Uploaded
photon_sdk-0.1.0.tar.gz 49.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for photon-sdk 0.1.0
File Interpreter ABI Platform
photon_sdk-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 87.2 kB

Release files / photon_sdk-0.1.0.tar.gz

Download URL photon_sdk-0.1.0.tar.gz
Size 49.6 kB
Tags Source
SHA-256 checksum
How to use checksums
0ff10a8c39562321302e5c3c73776d410dd4e3764a1243f58e39a5b4486d3737
BLAKE2b-256 checksum
How to use checksums
b23c72f64914a8cb345a74025c2dbba1bdc3632c232fb566f6c2fbc4321642a1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / photon_sdk-0.1.0-py3-none-any.whl

Download URL photon_sdk-0.1.0-py3-none-any.whl
Size 37.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d53701eb9736fc63cd804569d94af694d018e4e2cb2e08e45bb0390b038ae594
BLAKE2b-256 checksum
How to use checksums
2bf5a67fbbeac50ab202ce61568efca0b33855d06d82f9bc4c856f174a750480
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page