Standards & Conventions
Overview
Bushel strives to incorporate industry standards within our APIs wherever possible. These standards enable greater interoperability while also increasing the quality and usefulness of the data that flows through our platform. This document provides and overview of many of the standards and conventions utilized throughout Bushel’s ingestion APIs.
Standards
Timestamps
RFC 3339
Nearly all timestamps in the Ingestion API are in the RFC 3339 format. RFC 3339 is a simple, standard, and widely used format for representing a moment in time.
2024-08-15T16:40:46-05:00
RFC 3339 timestamps are formatted as {year}-{month}-{day}T{hour}:{minute}:{second}{timezoneOffset}
, using the full 4-digit year with 2-digits for all other components. The timezone offset must be provided and accurate, but does not need to reflect the timezone of the location the event occurred.
For example, the weigh_in_at
timestamp on a Ticket for a load delivered to Fargo could either be represented as 2024-08-15T09:40:46-05:00
or 2024-08-15T14:40:46+00:00
. Both of these timestamps represent the same moment in time, and are treated the same within Bushel’s platform. The first example represents the wall clock time (09:40
) of the delivery with a five-hour timezone offset (-05:00
) while in the second example the delivery time is represented in UTC time (with a timezone offset of +00:00
).
Note that for locations that celebrate daylights savings time, the timezone offset is not consistent and will change during the year.
Generally, these timestamps are converted to UTC for storage in Bushel’s backend systems and are converted to the user’s local timezone when displayed.
Currencies
ISO 4217
Bushel prefers currencies to be specified by the currency’s ISO 4217 alphanumeric currency code. Common examples are USD
(United States dollar), CAD
(Canadian dollar), and MXN
(Mexican peso).
While we prefer currencies to be in the ISO 4217 format to eliminate ambiguity, our ingestion systems will accept other designations.
Country Codes
ISO 3166-1 alpha-3
Bushel prefers country codes to be specified in the ISO 3166-1 alpha-3 standard. Common examples are USA
(United States), CAN
(Canada), and MEX
(Mexico).
While we prefer currencies to be in the ISO 3166-1 alpha-3 format to eliminate ambiguity, our ingestion systems will accept other designations.
Phone Numbers
E.164
All phone numbers must be in E.164 format unless otherwise noted. An E.164-formatted phone number consists of a plus sign (+
), country code, and full subscriber number. For example, the American number (701) 555-0123
is represented in E.164 as +17015550123
Conventions
Record Identifiers
Within an integration, each record is uniquely identified by its 'type' (for example tickets
, splits
, pricing-lines
) and its id
.
Record Relationships
A relationship between records is made when the id field of {type} matches the {type}_id field of another record. For example, a split is associated with ticket with "id": "123789"
when the split includes "ticket_id": "123789"
.
Order of Data Loading
Bushel is designed to accommodate data arriving out of order. A record may declare a relationship to another record prior to the referenced record existing. For example, a Split may reference a ticket_id
of a Ticket that has not yet been received by Bushel or a Contract Pricing Line may have a contract_id
referencing a Contract that does not yet exist in our system.
Additionally, a given record is not stored if an older version of it has been received, see Updated At.
Creating, Updating, and Deleting Records
All records are created, updated, and deleted using the same push API endpoint using different operations to modify and delete each record type.
Each update or delete operation overwrites and replaces any previously received record of the same 'type' and id
in its entirety.
Creating
Bushel creates records when we receive a record via the update-{type}
operation that we have not seen before, as identified by the records type and id
.
Updating
In addition to creating records, the update-{type}
operation is also used for updates.
Bushel does not support partial updates to records (i.e. PATCHing) at this time. As such, the record must be sent in its entirety with each update. All fields not explicitly set in an update for a record will be set to their default value (typically null
).
The update-{type}
operation is idempotent for end users and data integrity.
Deleting
Each record sent to Bushel that no longer exists in the originating dataset must be explicitly deleted from Bushel. When a delete request is received, Bushel will only delete that one record and will not cascade deletes or delete any other associated records. A deleted record is marked as deleted rather than permanently removed from Bushel’s platform (also known as soft deletion). If compliance or other business needs require records to be removed entirely, contact [email protected].
For example, to fully delete all data for a Contract, the contract
, its pricing pricing-lines
, and any associated pricing-histories
records must all be deleted from Bushel individually. In practice, deleting a Contract record prevents any associated Pricing Lines and Pricing Histories objects from being viewable to users (as the latter two record types are only associated to users via the Contract) but these associated records themselves would not be deleted from Bushel.
update-ticket-ticket-applications and update-ticket-splits are an exception to the 'records must be updated and deleted individually' rule. These APIs accept a 'snapshot' of all Ticket Applications or Splits (respectively) currently associated with the Ticket. Any records associated with the Ticket within Bushel but not included in the update request will be deleted.
|
Records are deleted via the push API using the delete-{type}
operation which is available for all record types. This operation will functionally remove the specified records from Bushel’s systems. An example payload which deletes two tickets is given below:
{
"data": [
{
"delete-tickets": {
"tickets": [
{
"id": "7-1a"
},
{
"id": "abc123"
}
]
}
}
]
}
More examples are available in our Router API Reference under the 'delete records' operation of the Data Push API.
Records may also be deleted by setting the deleted_at
timestamp on the record, when available. However, this method requires that all required fields of the record also be populated.
If your integration is not capable of identifying records which should be deleted from Bushel’s system, the Scrubbing process is an alternative method of keeping Bushel’s dataset in sync.
Updated At Timestamp
Bushel will ignore any records that have an updated_at
timestamp that is older than a previously processed updated_at
. This is to help ensure that only the most recent version of a record is processed. If a record with an older updated_at
timestamp is sent, Bushel will not return any errors to the sender.