Commercial Invoices API Tutorial

Overview

The Commercial Invoices API provides you with the ability to create and update an invoice, retrieve a list of your invoices, and even retrieve the details of an individual invoice.

Note that the endpoint has to be enabled on a per client basis, and requires discussion between you, the client, and your assigned broker to be enabled.

Endpoints

  GET /commercial_invoices
 POST /commercial_invoices
PATCH /commercial_invoices
  GET /commercial_invoices/id

The Commercial Invoices JSON Object

The Commercial Invoices JSON object is used in every HTTP request. Take a look at its elements before you go on.

Creating a Commercial Invoice

You’ll need to request specific permission to access both the create and update APIs. Once you’ve received permission, you’ll create the invoice by making an HTTP POST request:

curl -X "POST" "https://api.flexport.com/commercial_invoices" \
     -H "Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
     -H "Flexport-Version: 3" \
     -H "Content-Type: application/json" \
     -d $'{
            "shipment_id": 652551,
            "invoice_number":"CA994444",
            "currency_code": "USD",
            "is_related_parties": "true",
            "involved_parties": [
                {
                    "type": "seller",
                    "company_entity_ref": "id-12345"
                } 
            ],
            "proration_amount": 
            {
                "amount": "4430.95",
                "currency_code": "USD"
            },
            "line_items": [
                {
                    "document_line_number": 1,
                    "purchase_order_number": "61901",
                    "country_of_origin": "CN",
                    "product_sku": "ACME-33x3d3",
                    "quantity": {
                        "value": 0,
                        "unit": "pcs"
                    },
                    "value": {
                        "amount": "12.34",
                        "currency_code": "USD"
                    },
                    "price_per_unit": {
                        "amount": "12.34",
                        "currency_code": "USD"
                    },
                    "gross_weight": {
                        "value": 2300.4,
                        "unit": "kg"
                    },
                    "volume": {
                        "value": 472.62,
                        "unit": "cbm"
                    }          
                }
            ],
            "metadata": [
                {
                    "name": "newKey",
                    "value": ["newValue"]
                }
            ]
        }'

The following elements are required:

  • invoice_number
  • currency_code
  • proration_amount
  • line_items

The following elements are optional:

  • is_related_parties
  • metadata
  • involved_parties

Either shipment_id or shipment_ref_name (a string) can be passed along so long as only one or the other is included.

involved_parties is composed of a type and a company_entity_ref, which are both required within the parent object. company_entity_ref can be used in other requests you may make later on.

type must be one of the following:

  • origin_agent
  • buyer
  • seller
  • consignee
  • shipper
  • import_customs_agent
  • export_customs_agent
  • importer_of_record
  • forwarding_agent
  • destination_agent
  • trucking_broker
  • origin_warehouse
  • destination_warehouse
"involved_parties": [
    {
        "type": "seller",
        "company_entity_ref": "id-12345"
    } 
]

Since a monetary amount is an inherent element of an invoice, currency_code is naturally required. Valid values follow standard ISO currency codes (https://en.wikipedia.org/wiki/ISO_4217).

While required, a line_items object contains quite a few elements. It is covered here, so we’re not going to review it here.

Finally, though not required, the metadata element is an object which is a set of custom key-values (keys are strings, values are arrays of strings) which is always the consignee's list of keys. Note that the metadata keys must be configured in the Flexport UI prior to being used.

After a succesful request, you’ll recieve a response similar to this one:

{
    "_object": "/api/response",
    "self": "https://api.flexport.com/commercial_invoices",
    "version": 3,
    "data": {
        "metadata": {
            "newKey": "newValue"
        },
        "_object": "/commercial_invoice",
        "id": "zpr5KZKXLOxX85z3scOKIA",
        "invoice_number": "CA994444",
        "digitization_status": null,
        "involved_parties": [
            {
                "_object": "/customs/involved_party",
                "address": {
                    "_object": "/address",
                    "street_address": "1234 Business Street",
                    "street_address2": "Suite 2",
                    "city": "City",
                    "state": "State",
                    "country": "Germany",
                    "country_code": "DE",
                    "zip": "65432",
                    "unlocode": null,
                    "timezone": "Europe/Berlin",
                    "ref": null
                },
                "name": "Warehouse",
                "type": "seller",
                "company_entity": null
            }
        ],
        "is_related_parties": true,
        "line_items": [
            {
                "metadata": {},
                "_object": "/commercial_invoice_line_item",
                "document_line_number": 1,
                "price_per_unit": {
                    "_object": "/money",
                    "amount": "12.34",
                    "currency_code": "USD"
                },
                "first_sale_value": null,
                "value": {
                    "_object": "/money",
                    "amount": "12.34",
                    "currency_code": "USD"
                },
                "net_value": {
                    "_object": "/money",
                    "amount": "0",
                    "currency_code": "USD"
                },
                "total_units": "0.0",
                "container_number": null,
                "purchase_order_number": "61901",
                "po_line_item_number": "",
                "weight": {
                    "value": 2300.4,
                    "unit": "kg",
                    "_object": "/quantity/weight"
                },
                "volume": {
                    "value": 472.62,
                    "unit": "cbm",
                    "_object": "/quantity/volume"
                },
                "net_weight": {
                    "value": 0,
                    "unit": "kg",
                    "_object": "/quantity/weight"
                },
                "net_net_weight": {
                    "value": 0,
                    "unit": "kg",
                    "_object": "/quantity/weight"
                },
                "manufacturer_address": null,
                "manufacturer_name": null,
                "product": {
                    "_object": "/api/refs/object",
                    "ref_type": "/product",
                    "link": "https://api.flexport.com/products/9678705",
                    "id": 9678705
                }
            }
        ],
        "manufacturer_addresses": [
            {
                "_object": "/address",
                "street_address": "1641 Settlers Lane",
                "street_address2": "STE 2918",
                "city": "Albany",
                "state": "MN",
                "country": "United States",
                "country_code": "US",
                "zip": "56307",
                "unlocode": "USAL2",
                "timezone": "America/Chicago",
                "ref": "id-312836"
            }
        ],
        "shipment": {
            "_object": "/api/refs/object",
            "ref_type": "/shipment",
            "link": "https://api.flexport.com/shipments/652551",
            "id": 652551
        },
        "total_unit_count": "0.0",
        "total_value": {
            "_object": "/money",
            "amount": "12.34",
            "currency_code": "USD"
        },
        "total_volume": {
            "value": 472.62,
            "unit": "cbm",
            "_object": "/quantity/volume"
        },
        "total_weight": {
            "value": 2300.4,
            "unit": "kg",
            "_object": "/quantity/weight"
        }
    },
    "error": null
}

which includes summary items such as invoice_number, total_value, total_unit_count, total_value and total_weight, as well as details including manufacturer_addresses and line_items, from which you’ll be able to create your invoice.

Update Your Invoice

The Commercial Invoices API allows you to update your invoice should you need to. In this case, you’re sending an HTTP PATCH request whose data includes the invoice_id element to specify the desired invoice:

curl -X "PATCH" "https://api.flexport.com/commercial_invoices" \
     -H "Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
     -H "Flexport-Version: 3" \
     -H "Content-Type: application/json" \
     -d $'{
        "invoice_number":"CA994444",
        "currency_code":"USD",
        "is_related_parties":"true",
        "proration_amount":[
            { 
                "amount":"5043.32",
                "currency_code":"USD"
            }
        ]
    }'

This request shows the elements which can be updated. Other than the invoice_number, all other elements are optional. It goes without saying that you’ll want to include some changed element in addition to an invoice_number in the data section of the request, otherwise, why bother?

The response will be similar to the one received in the create example above:

{
    "_object": "/api/response",
    "self": "https://api.flexport.com/commercial_invoices?page=2&per=10",
    "version": 2,
    "data": {
        "_object": "/api/collections/paginated",
        "prev": "https://api.flexport.com/commercial_invoices?page=1&per=10",
        "next": null,
        "data": [
            {
                "_object": "/commercial_invoices",
                "id": "abcxyz-23456-def",
                "invoice_number": "ABCDEFGHIJKLMNOP",
                "digitization_status": "complete",
                "manufacturer_addresses": [...],
                "total_value": {...},
                "total_unit_count": "12345",
                "total_weight": {...},
                "total_volume": {...},
                "line_items": [...],
                "shipment": {...}
            }
        ]
    }
}

(some elements are abbreviated for brevity)

Listing Commercial Invoices

Do you need to retrieve your complete set of invoices? Make an HTTP GET request to the List commercial invoices endpoint:

curl -X "GET" "https://api.flexport.com/commercial_invoices?page=1&per=20" \
     -H 'Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' \
     -H 'Flexport-Version: 3' \
     -H 'Accept: application/json' \

with the optional URL arguments page and per (the page you are requesting, and the number of items per page, respectively) to receive your list.

You'll receive the following response:

{
    "_object": "/api/response",
    "self": "https://api.flexport.com/commercial_invoices?page=2&per=10",
    "version": 2,
    "data": {
        "_object": "/api/collections/paginated",
        "prev": "https://api.flexport.com/commercial_invoices?page=1&per=10",
        "next": null,
        "data": [
            {
                "_object": "/commercial_invoices",
                "id": "abcxyz-23456-def",
                "invoice_number": "CA994444",
                "digitization_status": "complete",
                "manufacturer_addresses": [...],
                "total_value": {...},
                "total_unit_count": "12345",
                "total_weight": {...},
                "total_volume": {...},
                "line_items": [...],
                "shipment": {...}
            }
        ]
    }
}

You can filter your results using any of the following elements:

  • f.shipment.id
  • f.invoice_number
  • f.involved_party_seller_id
  • f.involved_party_seller_name

Get an Invoice's Details

It’s quite easy to obtain the details of an invoice: append the invoice id to the URL, and make an HTTP GET request

curl -X "GET" "https://api.flexport.com/commercial_invoices/abcxyz-23456-def" \
     -H 'Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' \
     -H 'Flexport-Version: 3' \
     -H 'Accept: application/json' \

Using it, we get back

{
    "_object": "/api/response",
    "self": "https://api.flexport.com/commercial_invoices/abcxyz-23456-def",
    "version": 2,
    "data": {
        "_object": "/commercial_invoice",
        "id": "abcxyz-23456-def",
        "invoice_number": "CA994444",
        "digitization_status": "complete",
        "manufacturer_addresses": [...],
        "total_value": {...},
        "total_unit_count": "12345",
        "total_weight": {...},
        "total_volume": {...},
        "line_items": [...],
        "shipment": {...}
    }
}

which are the details corresponding to that invoice id (again, abbreviated for clarity).

Error Handling

HTTP error codes, along with a description message within the JSON response, help you build your exception handling routines.

An example of an error response is shown below.

{
  "_object": "/api/error",
  "status": 400,
  "code": "invalid_pagination",
  "message": "Invalid Sort Direction. allowed values: desc, asc"
}

You’ll want to use the status and message fields to handle exceptions.