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_type string |
Type of document uploaded | receipt , invoice , folio |
Document:
Field | Description | Allowed Values |
---|---|---|
document_type string |
Type of document uploaded | receipt , invoice , folio |
non_conforming_reason string |
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_document boolean |
Denotes whether the file uploaded contains a document |
is_conforming boolean |
Denotes whether the document is conforming |
Outbound Webhooks:
Field | Description |
---|
API Resources - Updates
Document:
Field | Description |
---|---|
tip decimal |
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
xxxxxxxxxx
with 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.processed
outbound 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 OK
response status is achieved
Upload a Document, e.g.
POST /documents
request You’ll want to save the response, as it returns the document’s ID.
If Client registered a callback URL:
- Receival of a
document.processed
webhook message for the uploaded document - Using the
url
resource field in the webhook message’sdata
field, 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 OK
code 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 |
---|---|---|---|
id int |
Account ID | ||
company string |
Company name | ||
primary contact string |
Primary contact name | ||
email_address string |
Primary email address | ||
markets string array |
Markets enabled for account | US |
US , UK , AU , NZ , CA , IE , ZA , SG , DE |
country string |
Home country | ||
monthly_processed int |
Number of documents processed MTD | ||
total_processed int |
Total number of documents processed | ||
data_set string |
Data level enabled for account, corresponds to extraction level | L2 |
L1 , L2 , L3 , Custom |
status string |
Activity status for account | active , inactive , suspended |
|
created long |
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
xxxxxxxxxx
with 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
xxxxxxxxxx
with 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_contact string |
Primary contact |
email_address string |
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 |
---|---|---|---|
id string |
Base | Document ID | |
format string |
Base | Document’s Content-Type | image/jpeg , image/png , image/tiff *, application/pdf ,text/html , text/plain |
client_id string |
Base | Client-provided UID used to identify and/or link documents with a unique end user | |
client_country_id int |
Base | Home country of client_id |
|
processed long |
Base | Unix timestamp of document’s processing | |
processed_string string |
1 | Formatted string version of "processed" field |
YYYY-MM-DD |
market string array |
Base | Document’s origin market; Market of transaction | |
ocr_text string |
Base | OCR text extracted from document image | |
is_document boolean |
Base | Denotes whether the file uploaded contains a document | true , false |
is_conforming boolean |
Base | Denotes whether the document is conforming | true , false |
document_type string |
Base | Type of document uploaded | receipt , invoice , folio |
non_conforming_reason string |
Base | Reason as to why a document may have been marked "is_conforming":false |
|
Level 1 | |||
purchased long |
1 | Date of transaction | Unix timestamp in UTC;0 indicates inability to extract purchase date |
purchased_string string |
1 | Formatted string version of "purchased" field |
YYYY-MM-DD |
total decimal |
1 | Total amount of transaction including tip | |
currency string |
1 | National Currency of amount tendered | ISO codes |
payment_type string |
1 | Method of Payment for a Purchase | Defaults:American Express , Cash , Check , Discover , Mastercard , PaypPal , Visa |
merchant complex object |
|||
Level 2 | |||
subtotal decimal |
2 | Sum of item charges (can excl. or include VAT/tax depending on market) | |
tax decimal |
2 | Captured tax data (US Sales Tax, VAT, GST) rolled up | Sum of all taxes on document |
tip decimal |
2 | Value of tip | |
financial_values complex object |
2 | Array of financial values | Flexible representation of financial values on document; expect duplication of types, e.g. state and city tax |
attributes complex 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_items complex 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 |
---|---|---|---|
name string |
1 | Merchant Name (Not Normalized) | Potential for inconsistent names, not recommended for display purposes |
category string |
1 | Classifies the merchant by the type of goods/services provided | |
icon string |
1 | Generic image representing "category" |
|
is_tippable int |
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_name string |
2 | Standardized name for chain of stores | Recommended for display purposes |
expense_category string |
2 | IRS Expense Category corresponding to merchant | |
logo string |
2 | Merchant-specific logo associated with normalized merchant | |
tax_id string |
2 | VAT registration number as printed on document | |
registered_name int |
2 | VAT registered merchant name | |
branch complex object |
2 | Location-specific merchant information |
branch
Resource Fields:
Field | Level | Description | Allowed Values |
---|---|---|---|
phone string |
2 | Phone | unformatted phone number |
financial value
Resource Fields:
Field | Level | Description | Allowed Values |
---|---|---|---|
financial_value_type string |
2 | Type of financial values | tax, discount, subtotal, balance due, etc. |
financial_value decimal |
2 | Financial value |
attribute
Resource Fields:
Field | Level | Description | Allowed Values |
---|---|---|---|
attribute_type string |
2 | Type of attribute | description of attribute label, e.g. start date, end date, due date |
attribute_value string |
2 | Attribute value | If a date, then YYYY-MM-DD format |
receipt item
Resource Fields:
Field | Level | Description | Allowed Values |
---|---|---|---|
item_name string |
3 | Name of product or service | |
item_subtotal decimal |
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_date string |
4 | Date associated with item, e.g. hotel folio line-item charge date | YYYY-MM-DD |
item_type string |
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
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"
}
"Metadata" Form Fields
Field | Description | Allowed Values |
---|---|---|
format string (required) |
Document’s content-type | image/jpeg ,image/tiff *,image/png ,application/pdf |
client_id string |
Client-provided UID used to identify and/or link documents with a unique end user | 128 characters or less |
client_country_id int |
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_id string |
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 |
latitude decimal |
GPS Latitude from document capture | |
longitude decimal |
GPS Longitude from document capture | |
document_type string |
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
xxxxxxxxxx
with 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 |
---|---|---|
format string (required) |
Document’s content-type | text/html , text/plain |
from_address string (required) |
Email address that sent the digital document email | |
client_id string |
Client-provided UID used to identify and/or link documents with a unique end user | 128 characters or less |
client_country_id string |
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_id string |
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_address string |
Receiving email address | Defaults to: Enterprise API |
subject string |
Subject line of the email | Defaults to: Electronic Receipt |
received_datetime long |
Date of email receival | Unix timestamp in UTC; Defaults to: 0 |
document_type string |
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 |
---|---|---|
format string (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 |
---|---|---|---|
format string (required) |
Document’s content-type | image/jpeg image/png image/tiff *application/pdf text/html text/plain |
Paper Digital |
from_address string (required) |
Email address that sent the digital document email | Digital |
|
client_id string |
Client-provided UID used to identify and/or link documents with a unique end user | 128 characters or less | Paper Digital |
client_country_id string |
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 |
Paper Digital |
|
webhook_id string |
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 | Paper Digital |
latitude decimal |
GPS Latitude from document capture | Paper |
|
longitude decimal |
GPS Longitude from document capture | Paper |
|
to_address string |
Receiving email address | Defaults to: Enterprise API |
Digital |
subject string |
Subject line of the email | Defaults to: Electronic Receipt |
Digital |
received_datetime long |
Date of email receival | Unix timestamp in UTC; Defaults to: 0 |
Digital |
document_type string |
Type of document uploaded | receipt invoice folio |
Paper Digital |
*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
xxxxxxxxxx
with 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
xxxxxxxxxx
with 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 |
---|---|---|
id int |
Account ID | |
account_id int |
Account associated with webhook | |
url string |
Callback URL | |
token string |
Credential validating outbound webhook’s source | Max. 100 characters |
created long |
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
xxxxxxxxxx
with 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 |
---|---|---|
url string (required) |
Callback URL | |
token string |
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
xxxxxxxxxx
with 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
xxxxxxxxxx
with 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
xxxxxxxxxx
with 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 |
---|---|---|
url string (required) |
Callback URL | |
token string |
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.processed
document.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: Bearer
header.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 |
---|---|---|
id string |
Webhook ID | |
type string |
Document event type | document.processed , document.updated |
created long |
Date of webhook message creation | Unix timestamp in UTC |
data complex object |
data
Resource Fields:
Field | Description | Allowed Values |
---|---|---|
id string |
Document ID | |
url string |
Endpoint to get extracted data set | |
client_id string |
Client-provided UID used to identify unique end users | |
client_country_id int |
Home country of the client_id |
|
processed long |
Date of document’s processing | Unix timestamp in UTC |
client_token string |
Client-provided webhook identifier used to validate webhook’s source | "webhook_id" provided at document upload |
data_level string |
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? |