Partner Integration API (1.5.0)
API specification for freight forwarding system (FFS) partners integrating with BravoTran.
BravoTran uses an event-driven pull model to stay in sync with your freight forwarding system:
- Your system sends an event notification to BravoTran when an entity is created or updated.
- BravoTran reads the entity type and identifier from the event.
- BravoTran issues a
GETrequest to your API with the entity type and identifier. - Your API returns the entity as JSON per this specification.
BravoTran also POSTs approved invoices to your system for cost posting. When an invoice is approved in BravoTran, it sends a POST /payables-invoices request to your API with the invoice details. Your system must create or record the invoice accordingly.

If your system cannot reliably push live event notifications, you may instead implement the optional list endpoints GET /orgs, GET /jobs, and GET /payables-invoices. BravoTran will periodically poll them with an updated_after window, get back the identifiers of anything that changed, then call the existing single-entity detail endpoints to fetch each one. Implement either the events API or the list endpoints — not both. All three list endpoints must be implemented together; BravoTran's polling assumes complete coverage of all entity types.
Creates and updates are surfaced through the same filter: when an entity is created, set updated_at to the creation timestamp and it will appear in any subsequent polling response whose updated_after is at or before that timestamp. There is no separate "creation" feed.
| Term | Definition |
|---|---|
| FFS | Freight Forwarding System — your system |
| Company | A country-level entity in the FFS; maps to a BravoTran Account |
| Account | BravoTran's representation of a company/country |
| Org | A vendor, carrier, creditor, or debtor |
| Creditor | An org that issues payables invoices; referenced as creditor on invoices and accruals |
| Job | A consol (consolidation/master) or shipment (house) |
| Accrual | An expected charge on a job |
| Charge Line | A line item on a payables invoice |
| Payables Invoice | AP invoice from a creditor |
| Outbound Payables Invoice | Approved invoice posted from BravoTran to the partner's system for cost posting |
BravoTran maps a Company in the FFS to an Account in BravoTran. Often a company represents a country. It is acceptable to have more than one account for a country if that country has multiple companies, but a single account must never represent multiple companies or countries.
external_id— Unique, immutable identifier for every entity. Used as the foreign key between systems. Typically the primary key in your database. Not visible to end users. The exampleexternal_idvalues throughout these docs are GUIDs, but they don't have to be — anexternal_idis whatever the stable identifier for the entity is in the FFS.updated_at— ISO 8601 timestamp of when the entity was last modified. BravoTran uses this as a version marker to prevent overwriting with stale data. For jobs, this must update when any child data changes (e.g., accrual added/edited, shipment added to consol). On creation,updated_atmust be set to (at least) the creation timestamp so newly created entities appear in polling responses alongside updates — the polling endpoints make no distinction between creates and updates.- Amounts — Wherever there is an amount, a corresponding
currency(ISO 4217) must be provided. - Local vs. overseas amounts —
local_amountis in the account's local currency (the currency of the country the forwarder operates in).overseas_amountis in the vendor's currency — whatever currency the charge or invoice is denominated in. The two may be the same (e.g., a domestic vendor). - Country codes — Country fields use ISO 3166-1 alpha-2 two-letter codes.
- Nested references — Related entities are represented as nested objects containing at minimum an
external_id. - Error codes — Error responses use
lower_snakecodes in both directions. BravoTran keys off the HTTP status rather than partner error bodies.
Staff data is provided via flat file — typically a spreadsheet export from the FFS. Any format your FFS can export works; field names don't matter as long as the required contents are present. If you don't have an existing export, use the recommended format, which lists each field and whether it is required. Alternatively, implement GET /staff and BravoTran will fetch staff data from your API instead.
Charge code data is provided via flat file — typically a spreadsheet export from the FFS. Any format your FFS can export works; field names don't matter as long as the required contents are present. If you don't have an existing export, use the recommended format, which lists each field and whether it is required. Alternatively, implement GET /charge-codes and BravoTran will fetch charge code data from your API instead. Accruals and charge lines reference charge codes by external_id; the mapping is maintained through the charge code data.
Tax code data is provided via flat file — typically a spreadsheet export from the FFS. Any format your FFS can export works; field names don't matter as long as the required contents are present. If you don't have an existing export, use the recommended format, which lists each field and whether it is required. Alternatively, implement GET /tax-codes and BravoTran will fetch tax code data from your API instead.
Each direction of communication supports one of the following authentication methods, agreed upon during onboarding:
BravoTran → Partner (partner-hosted endpoints):
- OAuth 2.0 — Client credentials flow
- Bearer Token — Static token in the
Authorizationheader
Partner → BravoTran (POST /events):
- OAuth 2.0 — Client credentials flow
- Token — API token in the
Authorizationheader, formatted asToken token=<token> - API Key — API token in the
x-api-keyheader
- Charge codes returned by
GET /charge-codesnow include a requiredcharge_typefield classifying the charge asfreight,origin,destination, orother.
- Renamed the
orgreference tocreditoron job accruals (GET /jobs/{external_id}), payables invoices (GET /payables-invoices/{external_id}), and outbound payables invoices (POST /payables-invoices). The referenced entity is still an org fetched via the/orgsendpoints; the key now reflects the role the org plays on these records.
- Payables invoice responses now include a
statusfield (draftorposted) — in bothGET /payables-invoices/{external_id}and thePOST /payables-invoicesresponse body. POST /payables-invoicescharge lines now always include anaccrualreference whoseexternal_idmatches an accrual returned byGET /jobs/{external_id}(nullwhen the charge line has no matching accrual).- Job accruals now include a
tax_codereference. Like other tax fields, it is optional for non-tax / US-based accounts. - Added supporting data endpoints —
GET /staff,GET /charge-codes, andGET /tax-codes— as an alternative to flat file delivery of staff, charge code, and tax code data. POST /payables-invoicesnow documents a409response with error codeduplicate_invoice, returned when an invoice with the sameinvoice_numberalready exists for the org.
POST /payables-invoicesrequests no longer include anexternal_id. Your system generates its own identifier for the created invoice and returns it asexternal_idin the 200 response. BravoTran stores that identifier and uses it forGET /payables-invoices/{external_id}.POST /eventserror responses now uselower_snakeerror codes (validation_error,invalid_json,unauthorized), matching the partner-hosted endpoints.