Introduction
Welcome to the Itemize Enterprise API documentation. The Itemize Enterprise API allows a client to upload payment documents and view the raw results in the form of a structured data set.
Sample code is available for reference in Shell, Java, and Python on the right. The Java code requires the Unirest library. The python code requires the Unirest and Json libraries.
To integrate the Itemize Enterprise API with your application, check out the Getting Started section for a step-by-step guide and workflow overview.
Releases
Upcoming
Increased Content-Length Thresholds
Released: March 2023
Summary
A new set of endpoints enables the increase of document image content-length thresholds to the following:
| Content-Type | Content-Length Requirements | Below Threshold Response | Above Threshold Response |
|---|---|---|---|
| Paper | |||
image/jpeg |
30KB - 30MB | {"error": "Minimum file size is 30KB"} |
{"error": "Maximum file size is 30MB"} |
image/png |
30KB - 30MB | {"error": "Minimum file size is 30KB"} |
{"error": "Maximum file size is 30MB"} |
image/tiff* |
30KB - 30MB | {"error": "Minimum file size is 30KB"} |
{"error": "Maximum file size is 30MB"} |
application/pdf |
30MB | No minimum. | {"error": "Maximum file size is 30MB"} |
| Digital | text/html |
< 30MB | No minimum. | {"error": "Maximum file size is 30MB"} |
text/plain |
< 30MB | No minimum. | {"error": "Maximum file size is 30MB"} |
*Contact us for details
Using Presigned URLs, clients upload the document images directly to the image store and then pass the metadata in a separate API call. View the new endpoints for more details.
Changelog
Feedback Loop
Released: October 15, 2020
Summary
A feedback mechanism has been implemented so Itemize may be alerted of any result accuracy modifications made by clients or their end users. Models may be enhanced as feedback is received for improved results.
View the endpoint for more details.
Invoices & Hotel Folios - Comprehensive Solution
Released: July 25, 2018
Summary
Invoices and hotel folios can be submitted for human review, which ensures the highest accuracy of an extracted data set. These documents will need to be distinguished from receipts by sending an additional "metadata" parameter on document upload.
Workflow:
Invoice and hotel folio processing follows a pipeline similar to receipt processing. Processing and webhook notifications remain the same.
On upload, send the parameter, "document_type":"invoice" for invoice documents and "document_type":"folio" for hotel folio documents. By default, Itemize considers any unspecified document a "receipt".
API Resources - Updates
"Metadata" Form Fields:
| Field | Description | Allowed Values |
|---|---|---|
document_typestring |
Type of document uploaded | receipt, invoice, folio |
Document:
| Field | Description | Allowed Values |
|---|---|---|
document_typestring |
Type of document uploaded | receipt, invoice, folio |
non_conforming_reasonstring |
Reason as to why a document may have been marked "is_conforming":false |
Comprehensive Solution
Released: July 1, 2018
Summary
Payment documents have the ability to be submitted for human review, which ensures the highest accuracy of an extracted data set. Clients may opt-in for this exciting new workflow. For existing integrations, processing is unchanged, as the review workflow occurs after core engine processing.
Workflow:
- During data extraction, a confidence score is assigned to each data field. If a confidence score falls below a given threshold, the document's field is forwarded for human verification.
- A
"document.processed"webhook message is sent to notify the client that the document's initial data set is available. - Once the document has been reviewed, a
"document.updated"webhook message is sent to notify the client that the document's data set has been updated.
API Resources - Updates
Document:
| Field | Description |
|---|---|
is_documentboolean |
Denotes whether the file uploaded contains a document |
is_conformingboolean |
Denotes whether the document is conforming |
Outbound Webhooks:
| Field | Description |
|---|
API Resources - Updates
Document:
| Field | Description |
|---|---|
tipdecimal |
Value of tip |
Outbound Webhooks:
| Field | Description |
|---|
See figure below for a tip processing workflow visualization:

File Size Limitations
Released February 14, 2018
File size requirements have been added to image uploads. Any image outside of the threshold will be rejected with a HTTP 400 error code and corresponding message. See below table for specifications:
Content Types:
| Content-Type | File Size Requirements | Below Threshold Response | Above Threshold Response |
|---|---|---|---|
| Paper | |||
image/jpeg |
30KB - 5MB | {"error": "Minimum file size is 30KB"} |
{"error": "Maximum file size is 5MB"} |
image/png |
30KB - 5MB | {"error": "Minimum file size is 30KB"} |
{"error": "Maximum file size is 5MB"} |
image/tiff* |
30KB - 5MB | {"error": "Minimum file size is 30KB"} |
{"error": "Maximum file size is 5MB"} |
application/pdf |
less than 5MB | No minimum. | {"error": "Maximum file size is 5MB"} |
| Digital | text/html |
less than 5MB | No minimum. | {"error": "Maximum file size is 5MB"} |
text/plain |
less than 5MB | No minimum. | {"error": "Maximum file size is 5MB"} |
*Contact us for details
Authentication
To authorize, use this code:
# With Python's Unirest library, just add the auth=(username, password) parameter to each request
import unirest
response = unirest.get("api_endpoint_here", auth=('', 'xxxxxxxxxx'))
print response.raw_body
// With Java's Unirest library, just add the basicAuth(String username, String password) method to each request
GetRequest body = Unirest
.get("api_endpoint_here")
.basicAuth("", "xxxxxxxxxx");
# Specify the API token as the password portion for inline authentication
curl -u :xxxxxxxxxx 'api_endpoint_here'
Make sure to replace
xxxxxxxxxxwith your API token.
In order to use the Enterprise API, clients will need an API token. Requests are authenticated using HTTP Basic Authorization. Use the supplied API token as the Basic Auth password; there is no username.
The Authorization header must be included in all requests in the following format:
Authorization: Basic xxxxxxxxxx
Getting Started
Before integrating the Enterprise API with your application, Itemize recommends understanding the API’s workflow. The Enterprise API serves as an Internet-facing entry/exit point for the Core Processing Engine. Once a document is ingested by the API, it is forwarded to the Core Engine for processing and extraction.
See figures below for an API workflow visualization for each document type:


Basic Request Flow:
- Upload a document, e.g.
POST /documents - Wait for
document.processedoutbound webhook, indicating processing is complete and the extracted data set is available - Get the document’s extracted data using the document’s ID returned in the webhook message, e.g.
GET /documents/<DOCUMENT-ID>
Step-By-Step Integration
Here, we’ll walk through the steps to create a fully-functioning integration between a client application and the Enterprise API.
Itemize recommends a client first upload documents to the API with the use of a REST client such as POSTMAN, Fiddler, etc. to test the API’s requests and responses.
- Upload a document
- Wait ~60 seconds to verify the document has finished processing
- Get the document’s data
Next, Itemize recommends working through a coded integration:
A decision should be made on how the client application will get each document’s extracted data set, as this setup will affect the request flow. Since document processing is asynchronous, Itemize has webhooks to notify the client when a document has finished processing and its extracted data set is available.
Clients can choose one of the following options to handle the asynchronous response:
- Client polls each document’s endpoint until the extracted data set is available, OR
- Client registers a webhook callback URL that will recieve messages when a document has finished processing
To register a callback URL:
- Add a new webhook URL, e.g.
POST /webhooks - Verify the callback URL has been registered using the
"id"field in the response, e.g.GET /webhooks/
To poll the document endpoint:
- Continous GET requests to the document’s endpoint until a
200 OKresponse status is achieved
Upload a Document, e.g.
POST /documentsrequest You’ll want to save the response, as it returns the document’s ID.
If Client registered a callback URL:
- Receival of a
document.processedwebhook message for the uploaded document - Using the
urlresource field in the webhook message’sdatafield, get the document’s extracted data set, e.g.GET /documents/request
If the Client polls the document’s endpoint:
- Client polls document’s endpoint until a
200 OKcode is achieved and the extracted data set exists in the response body.
Accounts
Clients are provided with an account that serves as the container for all uploaded documents and their data sets.
{
"id":155,
"company":"Enterprise Documentation Demo",
"primary_contact":"FirstName LastName",
"email_address":"email@gmail.com",
"markets":["US", "UK"],
"country":
{
"country_code":"US"
},
"monthly_processed":1736,
"total_processed":27807,
"data_set":"L2",
"status":"active",
"created":1460990424
}
Resource Fields:
| Field | Description | Default | Allowed Values |
|---|---|---|---|
idint |
Account ID | ||
companystring |
Company name | ||
primary contactstring |
Primary contact name | ||
email_addressstring |
Primary email address | ||
marketsstring array |
Markets enabled for account | US |
US, UK, AU, NZ, CA, IE, ZA, SG, DE |
countrystring |
Home country | ||
monthly_processedint |
Number of documents processed MTD | ||
total_processedint |
Total number of documents processed | ||
data_setstring |
Data level enabled for account, corresponds to extraction level | L2 |
L1, L2, L3, Custom |
statusstring |
Activity status for account | active, inactive, suspended |
|
createdlong |
Date of account creation | Unix timestamp in UTC |
Get Account Info
Example Request:
import unirest
response = unirest.get("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155", auth=('', 'xxxxxxxxxx'))
print response.raw_body
GetRequest response = Unirest
.get("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155")
.basicAuth("", "xxxxxxxxxx");
System.out.println(response.asString().getBody().toString());
curl -u :xxxxxxxxxx "https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155"
Make sure to replace
xxxxxxxxxxwith your API token.Example Response Body:
{
"status":"active",
"country":
{
"country_code":"US"
},
"total_processed":27807,
"markets":["US", "UK"],
"primary_contact":"FirstName LastName",
"created":1460990424,
"monthly_processed":1736,
"email_address":"email@gmail.com",
"data_set":"L2",
"id":155,
"company":"Enterprise Documentation Demo"
}
View the contact info, number of documents processed, and markets enabled for an an account.
HTTPS Request
GET https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/<ACCOUNT-ID>
Response Types
| Code | Description |
|---|---|
| 200 | Successful |
| 401 | Unauthorized |
Update Account Info
Example Request:
import unirest
import json
response = unirest.put("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155",
headers={"Content-Type":"application/json"},
params=json.dumps({"primary_contact":"UpdatedFirstName UpdatedLastName", "email_address":"updatedEmail@gmail.com"}),
auth=('', 'xxxxxxxxxx'))
print response.raw_body
HttpResponse<JsonNode> response = Unirest
.put("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155")
.basicAuth("", xxxxxxxxxx)
.header("Content-Type", "application/json")
.body("{\"primary_contact\":\"UpdatedFirstName UpdatedLastName\",
\"email_address\":\"updatedEmail@gmail.com\"}")
.asJson();
System.out.println(response.getBody().getObject().toString());
curl -u :xxxxxxxxxx
-X PUT
-H "Content-Type: application/json"
-d '{"primary_contact":"UpdatedFirstName UpdatedLastName", "email_address":"updatedEmail@gmail.com"}'
'https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155'
Make sure to replace
xxxxxxxxxxwith your API token.Example Response:
{
"status":"active",
"country":
{
"country_code":"US"
},
"total_processed":27807,
"markets":["US", "UK"],
"primary_contact":"FirstName LastName",
"created":1460990424,
"monthly_processed":1736,
"email_address":"email@gmail.com",
"data_set":"L2",
"id":155,
"company":"Enterprise Documentation Demo"
}
Updates contact info for an account.
HTTPS Request
PUT https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/<ACCOUNT-ID>
Content-Type
application/json
Data Params
| Field | Description |
|---|---|
primary_contactstring |
Primary contact |
email_addressstring |
Primary email address |
Response Types
| Code | Description |
|---|---|
| 200 | Successful |
| 401 | Unauthorized |
Documents
The Itemize API accepts the following document content types:
{
"id": "64233b41-4f00-4340-9362-caa26da43954",
"format": "image/jpeg",
"client_id": "user12345",
"client_country_id": 1,
"processed": 1459188044,
"processed_string": "2016-03-28",
"market": "US",
"ocr_text": "this is some sample text.",
"purchased": 1400457600,
"purchased_string": "2014-05-19",
"total": 11.60,
"currency": "USD",
"payment_type": "Mastercard",
"is_document": true,
"is_conforming": true,
"document_type": "receipt",
"non_conforming_reason": null,
"merchant": {
"name": "default_Pret A Manger",
"category": "Food & Dining",
"icon": "https://s3.amazonaws.com/mcc_icons/food.png",
"is_tippable": 1,
"normalized_name": "Pret A Manger",
"expense_category": "Dining & Entertainment",
"logo": "http://i.imgur.com/hsh5OCY.jpg",
"tax_id": null,
"registered_name": null,
"branch": {
"phone": "1234567890"
}
},
"subtotal": 9.98,
"tax": 0.62,
"tip": 1.00,
"financial_values": [
{
"financial_value_type": tax
"financial_value": 0.62
}
]
"attributes": null
"receipt_items": [
{
"item_name": "honey tangerine"
"item_subtotal": 2.99
"item_date": null
}
{
"item_name": "avocado pinenut wrap"
"item_subtotal": 6.99
"item_date": null
}
]
}
Content Types:
| Content-Type | File Size Requirements |
|---|---|
| Paper | |
image/jpeg |
30KB - 5MB |
image/png |
30KB - 5MB |
image/tiff* |
30KB - 5MB |
application/pdf |
less than 5MB |
| Digital | text/html |
less than 5MB |
text/plain |
less than 5MB |
*Contact us for details
Resource Fields:
| Field | Level | Description | Allowed Values |
|---|---|---|---|
idstring |
Base | Document ID | |
formatstring |
Base | Document’s Content-Type | image/jpeg, image/png, image/tiff*, application/pdf,text/html, text/plain |
client_idstring |
Base | Client-provided UID used to identify and/or link documents with a unique end user | |
client_country_idint |
Base | Home country of client_id |
|
processedlong |
Base | Unix timestamp of document’s processing | |
processed_stringstring |
1 | Formatted string version of "processed" field |
YYYY-MM-DD |
marketstring array |
Base | Document’s origin market; Market of transaction | |
ocr_textstring |
Base | OCR text extracted from document image | |
is_documentboolean |
Base | Denotes whether the file uploaded contains a document | true, false |
is_conformingboolean |
Base | Denotes whether the document is conforming | true, false |
document_typestring |
Base | Type of document uploaded | receipt, invoice, folio |
non_conforming_reasonstring |
Base | Reason as to why a document may have been marked "is_conforming":false |
|
| Level 1 | |||
purchasedlong |
1 | Date of transaction | Unix timestamp in UTC;0 indicates inability to extract purchase date |
purchased_stringstring |
1 | Formatted string version of "purchased" field |
YYYY-MM-DD |
totaldecimal |
1 | Total amount of transaction including tip | |
currencystring |
1 | National Currency of amount tendered | ISO codes |
payment_typestring |
1 | Method of Payment for a Purchase | Defaults:American Express, Cash, Check, Discover, Mastercard, PaypPal, Visa |
merchantcomplex object |
|||
| Level 2 | |||
subtotaldecimal |
2 | Sum of item charges (can excl. or include VAT/tax depending on market) | |
taxdecimal |
2 | Captured tax data (US Sales Tax, VAT, GST) rolled up | Sum of all taxes on document |
tipdecimal |
2 | Value of tip | |
financial_valuescomplex object |
2 | Array of financial values | Flexible representation of financial values on document; expect duplication of types, e.g. state and city tax |
attributescomplex object |
2 | Array of receipt attributes | Flexible representation of document fields; includes folio and invoice fields such as start date, end date, due date |
| Level 3 | |||
receipt_itemscomplex object |
3/4 | Array of receipt items |
*Contact us for details
merchant Resource Fields:
In the event that Itemize cannot resolve a merchant using the data within a document, a merchant will still exist in the response object. The merchant will have a default name of 'Merchant' and a default normalized_name of 'Merchant'.
| Field | Level | Description | Allowed Values |
|---|---|---|---|
namestring |
1 | Merchant Name (Not Normalized) | Potential for inconsistent names, not recommended for display purposes |
categorystring |
1 | Classifies the merchant by the type of goods/services provided | |
iconstring |
1 | Generic image representing "category" |
|
is_tippableint |
1 | Subjective merchant category field denotes whether a merchant is typically ‘tippable’ | 'Tippable’ merchant categories rollup to:Food & Dining, Entertainment, and Transportation > Taxi & Car Services |
Level 2 |
|||
normalized_namestring |
2 | Standardized name for chain of stores | Recommended for display purposes |
expense_categorystring |
2 | IRS Expense Category corresponding to merchant | |
logostring |
2 | Merchant-specific logo associated with normalized merchant | |
tax_idstring |
2 | VAT registration number as printed on document | |
registered_nameint |
2 | VAT registered merchant name | |
branchcomplex object |
2 | Location-specific merchant information |
branch Resource Fields:
| Field | Level | Description | Allowed Values |
|---|---|---|---|
phonestring |
2 | Phone | unformatted phone number |
financial value Resource Fields:
| Field | Level | Description | Allowed Values |
|---|---|---|---|
financial_value_typestring |
2 | Type of financial values | tax, discount, subtotal, balance due, etc. |
financial_valuedecimal |
2 | Financial value |
attribute Resource Fields:
| Field | Level | Description | Allowed Values |
|---|---|---|---|
attribute_typestring |
2 | Type of attribute | description of attribute label, e.g. start date, end date, due date |
attribute_valuestring |
2 | Attribute value | If a date, then YYYY-MM-DD format |
receipt item Resource Fields:
| Field | Level | Description | Allowed Values |
|---|---|---|---|
item_namestring |
3 | Name of product or service | |
item_subtotaldecimal |
3 | Subtotal of item | Typically presented as item_quantity * item_unit_price; less item_discount and plus item_shipping, item_handling, and item_tax |
item_datestring |
4 | Date associated with item, e.g. hotel folio line-item charge date | YYYY-MM-DD |
item_typestring |
4 | Type associated with item | Currently, only available type is tax |
*DEPRECATED* Upload Document
Submit a payment document to Itemize for data extraction.
HTTPS Request
POST https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/<ACCOUNT-ID>/documents
Content-Type
multipart/form-data
Paper
Example Paper Requests:
# JPEG Document
import unirest
import json
response = unirest.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents",
params={
"metadata":json.dumps(
{
"format":"image/jpeg",
"document_type":"receipt",
"latitude": 32.887993,
"longitude": -96.766574,
"client_id": "6g3fgh7h2s-557h-225c-81a3-yyoc8218788",
"client_country_id":1,
"webhook_id": "ADJSwejn23opds92"
}),
"document": open("images/receipt.jpeg", 'rb')},
auth=('', 'xxxxxxxxxx'))
print response.raw_body
# PNG Document
import unirest
import json
response = unirest.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents",
params={
"metadata":json.dumps(
{
"format":"image/png",
"document_type":"receipt",
"latitude": 32.887993,
"longitude": -96.766574,
"client_id": "6g3fgh7h2s-557h-225c-81a3-yyoc8218788",
"client_country_id":1,
"webhook_id": "ADJSwejn23opds92"
}),
"document": open("images/receipt.png", 'rb')},
auth=('', 'xxxxxxxxxx'))
print response.raw_body
# PDF Document
import unirest
import json
response = unirest.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents",
params={
"metadata":json.dumps(
{
"format":"application/pdf",
"document_type":"receipt",
"latitude": 32.887993,
"longitude": -96.766574,
"client_id": "6g3fgh7h2s-557h-225c-81a3-yyoc8218788",
"client_country_id":1,
"webhook_id": "ADJSwejn23opds92"
}),
"document": open("/images/receipt.pdf", 'rb')},
auth=('', 'xxxxxxxxxx'))
print response.raw_body
// JPEG Document
MultipartBody body = Unirest
.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents")
.basicAuth("", "xxxxxxxxxx")
.field("metadata",
"{\"format\": \"image/jpeg\",
\"latitude\": 32.887993,
\"longitude\": -96.766574,
\"client_id\": \"6g3fgh7h2s-557h-225c-81a3-yyoc8218788\",
\"client_country_id\":1,
\"webhook_id\": \"ADJSwejn23opds92\"}")
.field("document",
new File("images/receipt.jpeg"),
"image/jpeg");
System.out.println(body.asString().getBody().toString());
// PNG Document
MultipartBody body = Unirest
.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents")
.basicAuth("", "xxxxxxxxxx")
.field("metadata",
"{\"format\": \"image/png\",
\"latitude\": 32.887993,
\"longitude\": -96.766574,
\"client_id\": \"6g3fgh7h2s-557h-225c-81a3-yyoc8218788\",
\"client_country_id\":1,
\"webhook_id\": \"ADJSwejn23opds92\"}")
.field("document",
new File("images/receipt.png"),
"image/png");
System.out.println(body.asString().getBody().toString());
// PDF Document
MultipartBody body = Unirest
.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents")
.basicAuth("", "xxxxxxxxxx")
.field("metadata",
"{\"format\": \"application/pdf\",
\"latitude\": 32.887993,
\"longitude\": -96.766574,
\"client_id\": \"6g3fgh7h2s-557h-225c-81a3-yyoc8218788\",
\"client_country_id\":1,
\"webhook_id\": \"ADJSwejn23opds92\"}")
.field("document",
new File("/image/receipt.pdf"),
"application/pdf");
System.out.println(body.asString().getBody().toString());
# JPEG Document
curl -u :xxxxxxxxxx
-F metadata='{"format": "image/jpeg",
"document_type":"receipt",
"latitude": 32.887993,
"longitude": -96.766574,
"client_id": "6g3fgh7h2s-557h-225c-81a3-yyoc8218788",
"client_country_id":1,
"webhook_id": "ADJSwejn23opds92"}'
-F document=@/image/receipt.jpeg
'https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents'
# PNG Document
curl -u :xxxxxxxxxx
-F metadata='{"format": "image/png",
"document_type":"receipt",
"latitude": 32.887993,
"longitude": -96.766574,
"client_id": "6g3fgh7h2s-557h-225c-81a3-yyoc8218788",
"client_country_id":1,
"webhook_id": "ADJSwejn23opds92"}'
-F document=@/image/receipt.png
'https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents'
# PDF Document
curl -u :xxxxxxxxxx
-F metadata='{"format": "application/pdf",
"document_type":"receipt",
"latitude": 32.887993,
"longitude": -96.766574,
"client_id": "6g3fgh7h2s-557h-225c-81a3-yyoc8218788",
"client_country_id":1,
"webhook_id": "ADJSwejn23opds92"}'
-F document=@/image/receipt.pdf
'https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents'
Make sure to replace
xxxxxxxxxxwith your API token.Example Response:
{
"id": "64233b41-4f00-4340-9362-caa26da43954",
"format": "image/jpeg",
"document_type": "receipt",
"latitude": 32.887993,
"longitude": -96.766574,
"client_id": "6g3fgh7h2s-557h-225c-81a3-yyoc8218788",
"client_country_id":1,
"webhook_id": "ADJSwejn23opds92"
}
"Metadata" Form Fields
| Field | Description | Allowed Values |
|---|---|---|
formatstring (required) |
Document’s content-type | image/jpeg,image/tiff*,image/png,application/pdf |
client_idstring |
Client-provided UID used to identify and/or link documents with a unique end user | 128 characters or less |
client_country_idint |
Home country of end user - to be used along with client_id to aid in accurate data extraction and the mapping of documents to accounts’ end users |
|
webhook_idstring |
Client-provided webhook identifier used to verify the source of the outbound webhook; echoed back in webhook message as "client_token" |
6500 characters or less |
latitudedecimal |
GPS Latitude from document capture | |
longitudedecimal |
GPS Longitude from document capture | |
document_typestring |
Type of document uploaded | receipt, invoice, folio |
*Contact us for details
Digital
Example Digital Requests:
# HTML Document
import unirest
import json
response = unirest.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents",
params={
"metadata":json.dumps(
{
"format":"text/html",
"document_type":"receipt",
"latitude": 32.887993,
"longitude": -96.766574,
"client_id": "6g3fgh7h2s-557h-225c-81a3-yyoc8218788",
"client_country_id":1,
"webhook_id": "ADJSwejn23opds92"
}),
"document": open("/images/receipt.html", 'rb')},
auth=('', 'xxxxxxxxxx'))
print response.raw_body
# TEXT Document
import unirest
import json
response = unirest.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents",
params={
"metadata":json.dumps(
{
"format":"text/plain",
"document_type":"receipt",
"latitude": 32.887993,
"longitude": -96.766574,
"client_id": "6g3fgh7h2s-557h-225c-81a3-yyoc8218788",
"client_country_id":1,
"webhook_id": "ADJSwejn23opds92"
}),
"document": open("/images/receipt.txt", 'rb')},
auth=('', 'xxxxxxxxxx'))
print response.raw_body
// HTML Document
MultipartBody body = Unirest
.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents")
.basicAuth("", "xxxxxxxxxx")
.field("metadata",
"{\"format\":\"text/html\",
\"from_address\":\"orders@amazon.com\",
\"subject\":\"Your Recent Amazon Order\",
\"to_address\":\"testemail@gmail.com\",
\"received_datetime\":0,
\"client_id\": \"643ht811g6-23j7-77hg-12ff-bz55n99a768\",
\"client_country_id\":1,
\"webhook_id\": \"ADJSwejn23opds92\"}")
.field("document",
new File("/images/receipt.html"),
"text/plain");
System.out.println(body.asString().getBody().toString());
// TEXT Document
MultipartBody body = Unirest
.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents")
.basicAuth("", "xxxxxxxxxx")
.field("metadata",
"{\"format\":\"text/plain\",
\"document_type\":\"receipt\",
\"from_address\":\"orders@amazon.com\",
\"subject\":\"Your Recent Amazon Order\",
\"to_address\":\"testemail@gmail.com\",
\"received_datetime\":0,
\"client_id\": \"643ht811g6-23j7-77hg-12ff-bz55n99a768\",
\"client_country_id\":1,
\"webhook_id\": \"ADJSwejn23opds92\"}")
.field("document",
new File("/images/receipt.txt"),
"text/plain");
System.out.println(body.asString().getBody().toString());
# HTML Document
curl -u :xxxxxxxxxx
-F metadata='{"format":"text/html",
"document_type":"receipt",
"from_address":"orders@amazon.com",
"subject":"Your Recent Amazon Order",
"to_address":"testemail@gmail.com",
"received_datetime":0,
"client_id": "643ht811g6-23j7-77hg-12ff-bz55n99a768",
"client_country_id":1,
"webhook_id": "ADJSwejn23opds92"}'
-F document=@/images/receipt.html
'https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents'
# Text Document
curl -u :xxxxxxxxxx
-F metadata='{"format":"text/plain",
"document_type":"receipt",
"from_address":"orders@amazon.com",
"subject":"Your Recent Amazon Order",
"to_address":"testemail@gmail.com",
"received_datetime":0,
"client_id": "643ht811g6-23j7-77hg-12ff-bz55n99a768",
"client_country_id":1,
"webhook_id": "ADJSwejn23opds92"}'
-F document=@/images/receipt.txt
'https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents'
Make sure to replace
xxxxxxxxxxwith your API token.Example Response:
{
"id": "64233b41-4f00-4340-9362-caa26da43954",
"format": "text/html",
"document_type": "receipt",
"from_address":"orders@amazon.com",
"subject":"Your Recent Amazon Order",
"to_address":"testemail@gmail.com",
"received_datetime":0,
"client_id": "643ht811g6-23j7-77hg-12ff-bz55n99a768",
"client_country_id":1,
"webhook_id": "ADJSwejn23opds92"
}
Data Params
| Field | Description | Allowed Values |
|---|---|---|
formatstring (required) |
Document’s content-type | text/html, text/plain |
from_addressstring (required) |
Email address that sent the digital document email | |
client_idstring |
Client-provided UID used to identify and/or link documents with a unique end user | 128 characters or less |
client_country_idstring |
Home country of end user; to be used along with client_id to aid in accurate data extraction and the mapping of documents to clients’ end users |
|
webhook_idstring |
Client-provided webhook identifier used to verify the source of the outbound webhook; echoed back in webhook message as "client_token" |
6500 characters or less |
to_addressstring |
Receiving email address | Defaults to: Enterprise API |
subjectstring |
Subject line of the email | Defaults to: Electronic Receipt |
received_datetimelong |
Date of email receival | Unix timestamp in UTC; Defaults to: 0 |
document_typestring |
Type of document uploaded | receipt, invoice, folio |
Response Types
| Code | Description |
|---|---|
| 200 | Successful |
| 400 | Bad Request - Known Document Upload Error |
| 401 | Unauthorized |
| 415 | Unsupported Content-Type |
| 500 | Generic Server Error |
*NEW* Upload Document Flow
Submit a payment document to Itemize for data extraction.
Uploading a document image requires three steps:
| 1. | Request a Presigned URL | POST /document_urls |
| 2. | Upload the document image to the Presigned URL | POST https://s3.amazonaws.com/bucket.... |
| 3. | Send the metadata and initiate processing | POST /documents/<DOCUMENT-ID>/metadata |
Generate a Presigned URL
Example Request:
import unirest
import json
response = unirest.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/document_urls",
headers={"Content-Type":"application/json"},
params=json.dumps({
"format":"image/jpeg"
}),
auth=('', 'xxxxxxxxxx'))
print response.raw_body
HttpResponse<JsonNode> response = Unirest
.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/document_urls")
.basicAuth("", "xxxxxxxxxx")
.header("Content-Type", "application/json")
.body("{\"format\":\"image/jpeg\"}")
.asJson();
System.out.println(response.getBody().getObject().toString())
curl -u :xxxxxxxxxx
-X POST
-H 'Content-Type: application/json'
-d '{"format":"image/jpeg"}'
'https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/document_urls'
Make sure to replace xxxxxxxxxx with your API token.
Example Response:
{
"id": "64233b41-4f00-4340-9362-caa26da43954",
"imageKey": "64233b41-4f00-4340-9362-caa26da43954.jpeg",
"format": "image/jpeg",
"presignedFields": {
"url": "https://s3.amazonaws.com/bucket...",
"fields": {
"key": "64233b41-4f00-4340-9362-caa26da43954.jpeg",
"X-Amz-Algorithm": "AWS4-HMAC-SHA256",
"X-Amz-Credential": "ASDFQWERTY/20230217/us-east-1/s3/aws4_request",
"X-Amz-Date": "20230217T001518Z",
"X-Amz-Security-Token": "AsDfQwErTy//////////wEaCXV....",
"Policy": "eyJleHBpcmF0aW......",
"X-Amz-Signature": "3e2575cfcae...."
}
}
}
Example Request:
import unirest
import json
response = unirest.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/document_urls",
headers={"Content-Type":"application/json"},
params=json.dumps({
"format":"image/jpeg"
}),
auth=('', 'xxxxxxxxxx'))
print response.raw_body
HttpResponse<JsonNode> response = Unirest
.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/document_urls")
.basicAuth("", "xxxxxxxxxx")
.header("Content-Type", "application/json")
.body("{\"format\":\"image/jpeg\"}")
.asJson();
System.out.println(response.getBody().getObject().toString())
curl -u :xxxxxxxxxx
-X POST
-H 'Content-Type: application/json'
-d '{"format":"image/jpeg"}'
'https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/document_urls'
Make sure to replace xxxxxxxxxx with your API token.
Example Response:
{
"id": "64233b41-4f00-4340-9362-caa26da43954",
"imageKey": "64233b41-4f00-4340-9362-caa26da43954.jpeg",
"format": "image/jpeg",
"presignedFields": {
"url": "https://s3.amazonaws.com/bucket...",
"fields": {
"key": "64233b41-4f00-4340-9362-caa26da43954.jpeg",
"X-Amz-Algorithm": "AWS4-HMAC-SHA256",
"X-Amz-Credential": "ASDFQWERTY/20230217/us-east-1/s3/aws4_request",
"X-Amz-Date": "20230217T001518Z",
"X-Amz-Security-Token": "AsDfQwErTy//////////wEaCXV....",
"Policy": "eyJleHBpcmF0aW......",
"X-Amz-Signature": "3e2575cfcae...."
}
}
}
Generates a Presigned URL for document image upload.
HTTPS Request
POST https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/<ACCOUNT-ID>/document_urls
Content-Type
application/json
Request Body
| Parameter | Description | Allowed Values |
|---|---|---|
formatstring (required) |
Content-Type of Document Image | image/jpeg |
Response Types
| Code | Description |
|---|---|
| 200 | Successful, Document data set is available |
| 401 | Unauthorized |
| 400 | Bad Request, e.g. format field is missing |
Upload via Presigned URL
Example Request:
import unirest
import json
response = unirest.post("https://s3.amazonaws.com/bucket-name-here",
params={
"key":"64233b41-4f00-4340-9362-caa26da43954.jpeg",
"X-Amz-Algorithm": "AWS4-HMAC-SHA256",
"X-Amz-Credential": "ASDFQWERTY/20230217/us-east-1/s3/aws4_request"96.766574,
"X-Amz-Date": "20230217T001518Z",
"X-Amz-Security-Token":"AsDfQwErTy//////////wEaCXV....",
"Policy": "eyJleHBpcmF0aW......",
"X-Amz-Signature": "ADJSwejn23opds92...",
"Content-Type": "3e2575cfcae....",
"file": open("images/receipt.jpeg", 'rb')},
auth=('', 'xxxxxxxxxx'))
print response.raw_body
MultipartBody body = Unirest
.post("https://s3.amazonaws.com/bucket-name-here")
.basicAuth("", "xxxxxxxxxx")
.field("key","64233b41-4f00-4340-9362-caa26da43954.jpeg")
.field("X-Amz-Algorithm","AWS4-HMAC-SHA256")
.field("X-Amz-Credential","ASDFQWERTY/20230217/us-east-1/s3/aws4_request")
.field("X-Amz-Date","20230217T001518Z")
.field("X-Amz-Security-Token","AsDfQwErTy//////////wEaCXV....")
.field("Policy","eyJleHBpcmF0aW......")
.field("X-Amz-Signature","ADJSwejn23opds92...")
.field("Content-Type","image/jpeg")
.field("file",
new File("images/receipt.jpeg"),
"image/jpeg");
System.out.println(body.asString().getBody().toString());
curl -X POST
-F key="64233b41-4f00-4340-9362-caa26da43954.jpeg"
-F X-Amz-Algorithm="AWS4-HMAC-SHA256"
-F X-Amz-Credential="ASDFQWERTY/20230217/us-east-1/s3/aws4_request"
-F X-Amz-Date="20230217T001518Z"
-F X-Amz-Security-Token="AsDfQwErTy//////////wEaCXV...."
-F Policy="eyJleHBpcmF0aW......"
-F X-Amz-Signature="ADJSwejn23opds92..."
-F Content-Type="image/jpeg"
-F file=@/image/receipt.jpeg
'https://s3.amazonaws.com/bucket-name-here'
Make sure to replace xxxxxxxxxx with your API token.
Example Request:
import unirest
import json
response = unirest.post("https://s3.amazonaws.com/bucket-name-here",
params={
"key":"64233b41-4f00-4340-9362-caa26da43954.jpeg",
"X-Amz-Algorithm": "AWS4-HMAC-SHA256",
"X-Amz-Credential": "ASDFQWERTY/20230217/us-east-1/s3/aws4_request"96.766574,
"X-Amz-Date": "20230217T001518Z",
"X-Amz-Security-Token":"AsDfQwErTy//////////wEaCXV....",
"Policy": "eyJleHBpcmF0aW......",
"X-Amz-Signature": "ADJSwejn23opds92...",
"Content-Type": "3e2575cfcae....",
"file": open("images/receipt.jpeg", 'rb')},
auth=('', 'xxxxxxxxxx'))
print response.raw_body
MultipartBody body = Unirest
.post("https://s3.amazonaws.com/bucket-name-here")
.basicAuth("", "xxxxxxxxxx")
.field("key","64233b41-4f00-4340-9362-caa26da43954.jpeg")
.field("X-Amz-Algorithm","AWS4-HMAC-SHA256")
.field("X-Amz-Credential","ASDFQWERTY/20230217/us-east-1/s3/aws4_request")
.field("X-Amz-Date","20230217T001518Z")
.field("X-Amz-Security-Token","AsDfQwErTy//////////wEaCXV....")
.field("Policy","eyJleHBpcmF0aW......")
.field("X-Amz-Signature","ADJSwejn23opds92...")
.field("Content-Type","image/jpeg")
.field("file",
new File("images/receipt.jpeg"),
"image/jpeg");
System.out.println(body.asString().getBody().toString());
curl -X POST
-F key="64233b41-4f00-4340-9362-caa26da43954.jpeg"
-F X-Amz-Algorithm="AWS4-HMAC-SHA256"
-F X-Amz-Credential="ASDFQWERTY/20230217/us-east-1/s3/aws4_request"
-F X-Amz-Date="20230217T001518Z"
-F X-Amz-Security-Token="AsDfQwErTy//////////wEaCXV...."
-F Policy="eyJleHBpcmF0aW......"
-F X-Amz-Signature="ADJSwejn23opds92..."
-F Content-Type="image/jpeg"
-F file=@/image/receipt.jpeg
'https://s3.amazonaws.com/bucket-name-here'
Make sure to replace xxxxxxxxxx with your API token.
Uploads the document image using the Presigned URL.
HTTPS Request
POST https://s3.amazonaws.com/bucket....
Response Types
| Code | Description |
|---|---|
| 204 | Successful, Document image was uploaded |
| 400 | Bad Request, S3 error response Typically, document image content-length is outside of the allowed range: EntityTooSmall or EntityTooLarge |
| 403 | Forbidden, S3 error response Typically, form-data fields do not match the S3 Upload Policy |
Upload metadata and process
Example Request:
import unirest
import json
response = unirest.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents/64233b41-4f00-4340-9362-caa26da43954/metadata",
headers={"Content-Type":"application/json"},
params=json.dumps(
{
"format":"image/jpeg",
"document_type":"receipt",
"latitude": 32.887993,
"longitude": -96.766574,
"client_id": "6g3fgh7h2s-557h-225c-81a3-yyoc8218788",
"client_country_id":1,
"webhook_id": "ADJSwejn23opds92"
}),
auth=('', 'xxxxxxxxxx'))
print response.raw_body
MultipartBody body = Unirest
.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents/64233b41-4f00-4340-9362-caa26da43954/metadata")
.basicAuth("", "xxxxxxxxxx")
.header("Content-Type", "application/json")
.body("{\"format\": \"image/jpeg\",
\"latitude\": 32.887993,
\"longitude\": -96.766574,
\"client_id\": \"6g3fgh7h2s-557h-225c-81a3-yyoc8218788\",
\"client_country_id\":1,
\"webhook_id\": \"ADJSwejn23opds92\"}");
System.out.println(body.asString().getBody().toString());
curl -u :xxxxxxxxxx
-X POST
-H 'Content-Type: application/json'
-d '{"format": "image/jpeg",
"document_type":"receipt",
"latitude": 32.887993,
"longitude": -96.766574,
"client_id": "6g3fgh7h2s-557h-225c-81a3-yyoc8218788",
"client_country_id":1,
"webhook_id": "ADJSwejn23opds92"}'
'https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents/64233b41-4f00-4340-9362-caa26da43954/metadata'
Make sure to replace xxxxxxxxxx with your API token.
Example Response:
{
"id": "64233b41-4f00-4340-9362-caa26da43954",
"format": "image/jpeg",
"document_type": "receipt",
"latitude": 32.887993,
"longitude": -96.766574,
"client_id": "6g3fgh7h2s-557h-225c-81a3-yyoc8218788",
"client_country_id":1,
"webhook_id": "ADJSwejn23opds92"
}
Example Request:
import unirest
import json
response = unirest.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents/64233b41-4f00-4340-9362-caa26da43954/metadata",
headers={"Content-Type":"application/json"},
params=json.dumps(
{
"format":"image/jpeg",
"document_type":"receipt",
"latitude": 32.887993,
"longitude": -96.766574,
"client_id": "6g3fgh7h2s-557h-225c-81a3-yyoc8218788",
"client_country_id":1,
"webhook_id": "ADJSwejn23opds92"
}),
auth=('', 'xxxxxxxxxx'))
print response.raw_body
MultipartBody body = Unirest
.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents/64233b41-4f00-4340-9362-caa26da43954/metadata")
.basicAuth("", "xxxxxxxxxx")
.header("Content-Type", "application/json")
.body("{\"format\": \"image/jpeg\",
\"latitude\": 32.887993,
\"longitude\": -96.766574,
\"client_id\": \"6g3fgh7h2s-557h-225c-81a3-yyoc8218788\",
\"client_country_id\":1,
\"webhook_id\": \"ADJSwejn23opds92\"}");
System.out.println(body.asString().getBody().toString());
curl -u :xxxxxxxxxx
-X POST
-H 'Content-Type: application/json'
-d '{"format": "image/jpeg",
"document_type":"receipt",
"latitude": 32.887993,
"longitude": -96.766574,
"client_id": "6g3fgh7h2s-557h-225c-81a3-yyoc8218788",
"client_country_id":1,
"webhook_id": "ADJSwejn23opds92"}'
'https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents/64233b41-4f00-4340-9362-caa26da43954/metadata'
Make sure to replace xxxxxxxxxx with your API token.
Example Response:
{
"id": "64233b41-4f00-4340-9362-caa26da43954",
"format": "image/jpeg",
"document_type": "receipt",
"latitude": 32.887993,
"longitude": -96.766574,
"client_id": "6g3fgh7h2s-557h-225c-81a3-yyoc8218788",
"client_country_id":1,
"webhook_id": "ADJSwejn23opds92"
}
Uploads the document metadata and initiates processing.
HTTPS Request
POST https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/<ACCOUNT-ID>/documents/<DOCUMENT-ID>/metadata
Content-Type
application/json
Request Body
| Field | Description | Allowed Values | Format |
|---|---|---|---|
formatstring (required) |
Document’s content-type | image/jpegimage/pngimage/tiff*application/pdftext/htmltext/plain |
PaperDigital |
from_addressstring (required) |
Email address that sent the digital document email | Digital |
|
client_idstring |
Client-provided UID used to identify and/or link documents with a unique end user | 128 characters or less | PaperDigital |
client_country_idstring |
Home country of end user; to be used along with client_id to aid in accurate data extraction and the mapping of documents to clients’ end users |
PaperDigital |
|
webhook_idstring |
Client-provided webhook identifier used to verify the source of the outbound webhook; echoed back in webhook message as "client_token" |
6500 characters or less | PaperDigital |
latitudedecimal |
GPS Latitude from document capture | Paper |
|
longitudedecimal |
GPS Longitude from document capture | Paper |
|
to_addressstring |
Receiving email address | Defaults to: Enterprise API |
Digital |
subjectstring |
Subject line of the email | Defaults to: Electronic Receipt |
Digital |
received_datetimelong |
Date of email receival | Unix timestamp in UTC; Defaults to: 0 |
Digital |
document_typestring |
Type of document uploaded | receiptinvoicefolio |
PaperDigital |
*Contact us for details
Response Types
| Code | Description |
|---|---|
| 200 | Successful, Document data set is available |
| 401 | Unauthorized |
| 400 | Bad Request - Known Document Upload Error |
| 409 | Conflict - Duplicate request. The document id (guid) has already been processed |
| 500 | Generic Server Error |
Get Document Data
Example Request:
import unirest
response = unirest.get("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents/64233b41-4f00-4340-9362-caa26da43954", auth=('', 'xxxxxxxxxx'))
print response.raw_body
GetRequest body = Unirest
.get("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents/64233b41-4f00-4340-9362-caa26da43954")
.basicAuth("", xxxxxxxxxx);
System.out.println(body.asString().getBody().toString());
curl -u :xxxxxxxxxx
'https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents/64233b41-4f00-4340-9362-caa26da43954'
Make sure to replace
xxxxxxxxxxwith your API token.Example Response:
{
"id": "64233b41-4f00-4340-9362-caa26da43954",
"format": "image/jpeg",
"client_id": "user12345",
"client_country_id": 1,
"processed": 1459188044,
"processed_string": "2016-03-28",
"market": "US",
"ocr_text": "this is some sample text.",
"purchased": 1400457600,
"purchased_string": "2014-05-19",
"total": 11.60,
"currency": "USD",
"payment_type": "Mastercard",
"is_document": true,
"is_conforming": true,
"document_type": "receipt",
"non_conforming_reason": null,
"merchant": {
"name": "default_Pret A Manger",
"category": "Food & Dining",
"icon": "https://s3.amazonaws.com/mcc_icons/food.png",
"is_tippable": 1,
"normalized_name": "Pret A Manger",
"expense_category": "Dining & Entertainment",
"logo": "http://i.imgur.com/hsh5OCY.jpg",
"tax_id": null,
"registered_name": null,
"branch": {
"phone": "1234567890"
}
},
"subtotal": 9.98,
"tax": 0.62,
"tip": 1.00,
"financial_values": [
{
"financial_value_type": tax
"financial_value": 0.62
}
]
"attributes": null
"receipt_items": [
{
"item_name": "honey tangerine"
"item_subtotal": 2.99
"item_date": null
}
{
"item_name": "avocado pinenut wrap"
"item_subtotal": 6.99
"item_date": null
}
]
}
Retrieves the structured data set for a given document.
HTTPS Request
GET https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/<ACCOUNT-ID>/documents/<DOCUMENT-ID>
Response Types
| Code | Description |
|---|---|
| 200 | Successful, Document data set is available |
| 401 | Unauthorized |
| 404 | Resource Not Found - Document has not yet finished processing |
Feedback Loop for Documents
Example Request:
import unirest
response = unirest.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents/feedback",
headers={"Content-Type":"application/json"},
params=json.dumps{ "id": "64233b41-4f00-4340-9362-caa26da43954","format": "image/jpeg","client_id": "user12345","client_country_id": 1,"processed": 1459188044,"processed_string": "2016-03-28","market": "US","purchased": 1400457600,"purchased_string": "2014-05-19","total": 11.60,"currency": "USD","payment_type": "Mastercard","is_document": true,"is_conforming": true,"non_conforming_reason": null,,"merchant": {"name": "default_Pret A Manger","category": "Food & Dining","icon": "https://s3.amazonaws.com/mcc_icons/food.png","is_tippable": 1,"normalized_name": "Pret A Manger","expense_category": "Dining & Entertainment","logo": "http://i.imgur.com/hsh5OCY.jpg","tax_id": null,"registered_name": null,"branch": {"phone": "1234567890" } },"subtotal": 9.98,"tax": 0.62,"tip": 1.00,"financial_values": [{"financial_value_type": tax,"financial_value": 0.62}],"attributes": null,"receipt_items": [{"item_name": "honey tangerine","item_subtotal": 2.99,"item_date": null},{"item_name": "avocado pinenut wrap","item_subtotal": 6.99,"item_date": null}]}}),
auth=('', 'xxxxxxxxxx'))
print response.raw_body
HttpResponse<JsonNode> response = Unirest
.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents/feedback")
.basicAuth("", "xxxxxxxxxx")
.header("Content-Type", "application/json")
.body("{\"id\": \"64233b41-4f00-4340-9362-caa26da43954\",\"format\": \"image/jpeg\",\"client_id\": \"user12345\",\"client_country_id\": 1,\"processed\": 1459188044,\"processed_string\": \"2016-03-28\",\"market\": \"US\",\"purchased\": 1400457600,\"purchased_string\": \"2014-05-19\",\"total\": 11.60,\"currency\": \"USD\",\"payment_type\": \"Mastercard\",\"is_document\": true,\"is_conforming\": true,\"document_type\": \"receipt\",\"non_conforming_reason\": null,\"merchant\": {\"name\": \"default_Pret A Manger\",\"category\": \"Food & Dining\",\"icon\": \"https://s3.amazonaws.com/mcc_icons/food.png\",\"is_tippable\": 1,\"normalized_name\": \"Pret A Manger\",\"expense_category\": \"Dining & Entertainment\",\"logo\": \"http://i.imgur.com/hsh5OCY.jpg\",\"tax_id\": null,\"registered_name\": null,\"branch\": {\"phone\": \"1234567890\" } },\"subtotal\": 9.98,\"tax\": 0.62,\"tip\": 1.00,\"financial_values\": [
{\"financial_value_type\": tax, \"financial_value\": 0.62}], \"attributes\": null, \"receipt_items\": [{\"item_name\": \"honey tangerine\",\"item_subtotal\": 2.99,\"item_date\": null}, {\"item_name\": \"avocado pinenut wrap\",\"item_subtotal\": 6.99,\"item_date\": null}]}}")
.asJson();
System.out.println(response.getBody().getObject().toString())
curl -u :xxxxxxxxxx
-X POST
-H "Content-Type: application/json"
-d '{"id": "64233b41-4f00-4340-9362-caa26da43954","format": "image/jpeg","client_id": "user12345","client_country_id": 1,"processed": 1459188044,"processed_string": "2016-03-28","market": "US","purchased": 1400457600,"purchased_string": "2014-05-19","total": 11.60,"currency": "USD","payment_type": "Mastercard","is_document": true,"is_conforming": true,"document_type": "receipt","non_conforming_reason": null,"merchant": {"name": "default_Pret A Manger","category": "Food & Dining","icon": "https://s3.amazonaws.com/mcc_icons/food.png","is_tippable": 1,"normalized_name": "Pret A Manger","expense_category": "Dining & Entertainment","logo": "http://i.imgur.com/hsh5OCY.jpg","tax_id": null,"registered_name": null,"branch": {"phone": "1234567890" } },"subtotal": 9.98,"tax": 0.62,"tip": 1.00,"financial_values": [
{"financial_value_type": tax, "financial_value": 0.62}], "attributes": null, "receipt_items": [{"item_name": "honey tangerine","item_subtotal": 2.99,"item_date": null}, {"item_name": "avocado pinenut wrap","item_subtotal": 6.99,"item_date": null}]}}'
'https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/documents/feedback'
Make sure to replace
xxxxxxxxxxwith your API token.Example Response:
{
"id":11
}
Feeds back a *corrected* document data set to improve and enhance the platform document models.
HTTPS Request
POST https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/<ACCOUNT-ID>/documents/feedback
Data Parameters
| Parameter | Description | Allowed Values |
|---|---|---|
| document object (required) |
Document object, same format as the GET /documents/{GUID} response |
Response Types
| Code | Description |
|---|---|
| 201 | Successful, callback URL is registered |
| 401 | Unauthorized |
Registering Callback URLs
Webhooks serve as the real-time notification system for asynchronous document responses. A webhook notifies a client's application of particular events relating to a document’s workflow.
Accounts can register up to 3 callback URLs for a given API enviroment.
Resource Fields:
{
"id":105,
"account_id":155,
"url":"http://www.example.com",
"token":"dGVzdA==",
"created":1459199078
}
| Field | Description | Allowed Values |
|---|---|---|
idint |
Account ID | |
account_idint |
Account associated with webhook | |
urlstring |
Callback URL | |
tokenstring |
Credential validating outbound webhook’s source | Max. 100 characters |
createdlong |
Date of webhook creation | Unix timestamp in UTC |
Adding Callback URLs
Example Request:
import unirest
response = unirest.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/webhooks",
headers={"Content-Type":"application/json"},
params=json.dumps({"url":"http://testwebhookurl.com", "token":"dGVzdA=="}),
auth=('', 'xxxxxxxxxx'))
print response.raw_body
HttpResponse<JsonNode> response = Unirest
.post("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/webhooks")
.basicAuth("", "xxxxxxxxxx")
.header("Content-Type", "application/json")
.body("{\"url\":\"http://testwebhookurl.com\", \"token\":\"dGVzdA==\"}")
.asJson();
System.out.println(response.getBody().getObject().toString())
curl -u :xxxxxxxxxx
-X POST
-H "Content-Type: application/json"
-d '{"url":"http://testwebhookurl.com", "token":"dGVzdA=="}'
'https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/webhooks'
Make sure to replace
xxxxxxxxxxwith your API token.Example Response:
[
{
"id":105,
"url":"http://testwebhookurl.com",
"account_id":155,
"token":"dGVzdA=="
}
]
Registers a callback URL for a client’s account.
HTTPS Request
POST https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/<ACCOUNT-ID>/webhooks
Data Parameters
| Parameter | Description | Allowed Values |
|---|---|---|
urlstring (required) |
Callback URL | |
tokenstring |
Credential validating outbound webhook’s source | Max. 100 characters |
Response Types
| Code | Description |
|---|---|
| 201 | Successful, callback URL is registered |
| 401 | Unauthorized |
Get all Callback URLs
Example Request:
import unirest
response = unirest.get("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/webhooks",
auth=('', 'xxxxxxxxxx'))
print response.raw_body
GetRequest request = Unirest
.get("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/webhooks")
.basicAuth("", "xxxxxxxxxx");
System.out.println(request.asString().getBody().toString());
curl -u :xxxxxxxxxx
'https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/webhooks'
Make sure to replace
xxxxxxxxxxwith your API token.Example Response:
[
{
"id":49,
"url":"http://thisisawebhookurl.com",
"account_id":155
},
{
"id":105,
"url":"http://testwebhookurl.com",
"account_id":155
}
]
Retrieves all registered callback URLs.
HTTPS Request
GET https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/<ACCOUNT-ID>/webhooks
Response Types
| Code | Description |
|---|---|
| 200 | Successful |
| 401 | Unauthorized |
Get a Callback URL
Example Request:
import unirest
response = unirest.get("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/webhooks/105",
auth=('', 'xxxxxxxxxx'))
print response.raw_body
GetRequest request = Unirest
.get("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/webhooks/105")
.basicAuth("", "xxxxxxxxxx");
System.out.println(request.asString().getBody().toString());
curl -u :xxxxxxxxxx
'https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/webhooks/105'
Make sure to replace
xxxxxxxxxxwith your API token.Example Response:
{
"id":105,
"url":"http://testwebhookurl.com",
"account_id":155
}
Retrieves a specific callback URL.
HTTPS Request
GET https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/<ACCOUNT-ID>/webhooks/<WEBHOOK-ID>
Response Types
| Code | Description |
|---|---|
| 200 | Successful |
| 401 | Unauthorized |
Update a Callback URL
Example Request:
response = unirest.put("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/webhooks/105",
headers={"Content-Type":"application/json"},
params=json.dumps({"url":"http://www.updatedexample.com", "token":"dGhpc2lzZW5jb2RlZA=="}),
auth=('', 'xxxxxxxxxx'))
print response.raw_body
HttpResponse<JsonNode> response = Unirest
.put("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/webhooks/105")
.basicAuth("", "xxxxxxxxxx")
.header("Content-Type", "application/json")
.body("{\"url\":\"http://www.updatedexample.com\",
\"token\":\"dGhpc2lzZW5jb2RlZA==\"}")
.asJson();
System.out.println(response.getBody().getObject().toString());
curl -u :xxxxxxxxxx
-X PUT
-H "Content-Type: application/json"
-d '{"url":"http://www.updatedexample.com", "token":"dGhpc2lzZW5jb2RlZA=="}'
'https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/webhooks/105'
Make sure to replace
xxxxxxxxxxwith your API token.Example Response:
{
"id":105,
"url":"http://www.updatedexample.com",
"account_id":155,
"token":"dGhpc2lzZW5jb2RlZA=="
}
Updates a specific callback URL.
HTTPS Request
PUT https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/<ACCOUNT-ID>/webhooks/<WEBHOOK-ID>
Data Parameters
| Parameter | Description | Allowed Values |
|---|---|---|
urlstring (required) |
Callback URL | |
tokenstring |
Credential validating outbound webhook’s source | Max. 100 characters |
Response Types
| Code | Description |
|---|---|
| 200 | Successful, URL was updated |
| 401 | Unauthorized |
Delete a Callback URL
Example Request:
import unirest
response = unirest.delete("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/webhooks/105", auth=('', 'xxxxxxxxxx'))
print response.raw_body
HttpRequestWithBody response = Unirest
.delete("https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/webhooks/105")
.basicAuth("", "xxxxxxxxxx");
System.out.print(response.asString().getBody().toString());
curl -u :xxxxxxxxxx
-X DELETE
'https://sandbox.proapi.itemize.com/api/enterprise/v1/accounts/155/webhooks/105'
Example Response:
[]
Deletes a specific callback URL.
HTTPS Request
DELETE http://example.com/kittens/<ACCOUNT-ID>/webhooks/<WEBHOOK-ID>
Response Types
| Code | Description |
|---|---|
| 200 | Successful |
| 401 | Unauthorized |
Outbound Webhooks
Outbound webhooks are used to notify clients of document events. Itemize will deliver a webhook up to 3 times in a tight loop during each delivery attempt.
If the initial delivery is unsuccessful, the webhook will be retried 12 hours later and 36 hours later. If the webhook ultimately fails after the 36-hour retry, it will not be redelivered. It is the client’s responsibility to keep track of a document’s ID in the event of a failed webhook.
Retry Schedule:
- Inital delivery (3x Max.)
- 12 hours later (3x Max.)
- 36 hours later (3x Max.)
Multiple webhook deliveries (apart from retries) can occur for documents; notably those whose extracted data is below a given threshold. Currently, there are 2 types of webhooks, and if multiple deliveries occur, will occur in the following order:
document.processeddocument.updated
Client Response
The client’s application must repond to the outbound webhook with a 200 OK status to indicate receival. Any other status code indicates a failure, and the webhook will be retried according to the above retry schedule.
Security
Outbound webhooks allow clients to validate their origin in two ways:
With each callback URL registration, the
"token"field may be populated with an encrypted string that only the client knows. With each webhook notification, the"token"field will be sent as anAuthorization: Bearerheader.For each payment document, the
"webhook_id"resource parameter populated during upload is echoed in the webhook notifcation, aliased as the"client_token"field.
{
"id":"f7c30fa6-5095-4a65-8a74-1b6e6fe603a0",
"created":1459188055,
"type":"document.processed",
"data":
{
"client_token":"ADJSwejn23opds92",
"url":"/documents/64233b41-4f00-4340-9362-caa26da43954",
"processed":1459188044,
"id":"64233b41-4f00-4340-9362-caa26da43954",
"client_id":"user12345",
"client_country_id":1,
"data_level":"L2"
}
}
Resource Fields:
| Field | Description | Allowed Values |
|---|---|---|
idstring |
Webhook ID | |
typestring |
Document event type | document.processed, document.updated |
createdlong |
Date of webhook message creation | Unix timestamp in UTC |
datacomplex object |
data Resource Fields:
| Field | Description | Allowed Values |
|---|---|---|
idstring |
Document ID | |
urlstring |
Endpoint to get extracted data set | |
client_idstring |
Client-provided UID used to identify unique end users | |
client_country_idint |
Home country of the client_id |
|
processedlong |
Date of document’s processing | Unix timestamp in UTC |
client_tokenstring |
Client-provided webhook identifier used to validate webhook’s source | "webhook_id" provided at document upload |
data_levelstring |
Client-provided UID data set level, or if null, data set level for account | L1, L2, L3, Custom |
Processed
Example Request Body:
{
"id":"f7c30fa6-5095-4a65-8a74-1b6e6fe603a0",
"created":1459188055,
"type":"document.processed",
"data":
{
"client_token":"ADJSwejn23opds92",
"url":"/documents/64233b41-4f00-4340-9362-caa26da43954",
"processed":1459188044,
"id":"64233b41-4f00-4340-9362-caa26da43954",
"client_id":"user12345",
"client_country_id":1,
"data_level":"L2"
}
}
The document.processed webhook is sent for documents that have finished processing and have an extracted data set available at the document’s endpoint.
Updated
Example Request Body:
{
"id":"f7c30fa6-5095-4a65-8a74-1b6e6fe603a0",
"created":1459188055,
"type":"document.updated",
"data":
{
"client_token":"ADJSwejn23opds92",
"url":"/documents/64233b41-4f00-4340-9362-caa26da43954",
"processed":1459188044,
"id":"64233b41-4f00-4340-9362-caa26da43954",
"client_id":"user12345",
"client_country_id":1,
"data_level":"L2"
}
}
The document.updated webhook is sent for documents whose extracted data set has been updated.
Errors
The Enterprise API uses the following error codes:
| Error Code | Body | Meaning | What We Really Mean |
|---|---|---|---|
| 400 | {"error": "Minimum file size is 30KB"}{"error": "Maximum file size is 5MB"}{"error": "Incorrect format/mime-type for receipt document."}{"error": "Incorrect format for multipart/form-data. Please ensure document and metadata parameters are uploaded."}{"error": "'from_address' is missing in metadata. Please ensure the 'from_address' field is included in the metadata parameter."} |
Bad Request | One of the following:
|
| 401 | {"error": "access denied - invalid token or account"} |
Unauthorized | You probably forgot to include your API Token |
| 404 | {"message":"Resource not found"} |
Not Found | The document hasn’t finished pocessing yet |
| 405 | {"message":"Method not allowed."} |
Method Not Allowed | You're probably using the wrong HTTP verb |
| 415 | {"error": "multipart/form-data is the only content type allowed for document upload"} |
Unsupported Content-Type | Use multipart/form-data instead of application/json for document uploads |
| 500 | {"error": "An error has occurred during document upload. Please try again."} |
Internal Server Error | We had a problem parsing your request…try again later…did you include all of your JSON quotations? |